In rhino we can set material to every face of the Brep easily,but how to do this by api?
I want to set material not a color
Oops, sorry. I donβt know how to do that
Hi @duzhengjie1,
Just set BrepFace.MaterialChannelIndex with the rendering material channel index of your choice.
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
var rc = RhinoGet.GetOneObject("Select Brep", false, ObjectType.Brep, out var objref);
if (rc != Result.Success || null == objref)
return rc;
if (!(objref.Object() is BrepObject brep_object))
return Result.Failure;
// Create red material
var red_material = new Material { DiffuseColor = Color.Red };
var red_material_index = doc.Materials.Add(red_material);
// Create blue material with red material on one channel
var blue_material = new Material { DiffuseColor = Color.Blue };
var red_channel_index = blue_material.MaterialChannelIndexFromId(doc.Materials[red_material_index].Id, true);
var blue_material_index = doc.Materials.Add(blue_material);
// Change object material to blue material
brep_object.Attributes.MaterialIndex = blue_material_index;
brep_object.Attributes.MaterialSource = ObjectMaterialSource.MaterialFromObject;
// Set every second face material to red material channel
var brep = brep_object.BrepGeometry;
for (var i = 0; i < brep.Faces.Count; i++)
{
if (i % 2 == 0)
brep.Faces[i].MaterialChannelIndex = red_channel_index;
else
brep.Faces[i].ClearMaterialChannelIndex();
}
// Commit changes and redraw
brep_object.CommitChanges();
doc.Views.Redraw();
return Result.Success;
}
β Dale
Ok,thanks very much!I have did it.
Hi @dale,
Is there a way to apply a rendermaterial from ActiveDoc.RenderMaterials to a brepFace using c# in Rhino8?
ObjRef objRef = gs.Object(i); // Get each selected object
RhinoObject rhinoObj = objRef.Object(); // Get the RhinoObject
// Apply the material or perform operations on the rhinoObj
if (applyToSubelement && objRef.GeometryComponentIndex.ComponentIndexType == ComponentIndexType.BrepFace)
{
// Handle subelement (BrepFace) material application
var brep = rhinoObj.Geometry as Brep;
if (brep != null)
{
// Get the face index from the selected component
int brepFaceIndex = objRef.GeometryComponentIndex.Index;
BrepFace brepFace = brep.Faces[brepFaceIndex];
// Apply the material to the BrepFace
brepFace.MaterialChannelIndex = renderMaterial.ToMaterial(RenderTexture.TextureGeneration.Allow).Index;
rhinoObj.Attributes.MaterialSource = ObjectMaterialSource.MaterialFromParent; // Use material from parent
// Commit changes
rhinoObj.CommitChanges();
RhinoApp.WriteLine($"Material applied to BrepFace (index: {brepFaceIndex}).");
}
}
This is what I am trying to do.
Thanks
Hi @svichare,
Does assigning per-face materials using indices acquired from the RhinoDoc.Materials table not work?
β Dale
Hi Dale,
Thanks for getting back.
I have made a new topic of what I am trying to achieve here.
In a nutshell, I am trying to apply a material to subelement using MateialChannelIndex as suggested by you and Jussi Aaltonen in other topics but it still unsuccessful.
I have provided an example of my code in the linked topic.
Cheers
Srujan
@svichare - does the sample code I posted above work for you?
β Dale
No it does not. I tried doing the sample code with blue/red material and use the redChannelIndex but it didnt work for me yet.
I am using Rhino 8
I just copied/pasted my sample code (above) into a Rhino 8 test command, and it work as expected.
β Dale
i will give it another shot and get back.
Thanks!
Hi @dale ,
The sample code works as shown in your image.
I am trying to implement a way where i can only paint one of the faces per click instead of doing a for loop to paint every other surface.
// Apply the material or perform operations on the rhinoObj
if (applyToSubelement && objRef.GeometryComponentIndex.ComponentIndexType == ComponentIndexType.BrepFace)
{
// Get the face index from the selected component
int brepFaceIndex = objRef.GeometryComponentIndex.Index;
// check if chosen renderMaterial exists in the doc.Materials table or else add the material
var selectedDocMaterial = doc.Materials.FirstOrDefault(docMat => docMat.Id == selectedRenderMaterial.Id);
// adding material to doc.Material table returns its index
var selectedDocMaterialIndex = selectedDocMaterial == null ? doc.Materials.Add(selectedRenderMaterial.ToMaterial(RenderTexture.TextureGeneration.Allow)) : selectedDocMaterial.Index;
var parentObjectMaterialDuplicate = rhinoObj.GetMaterial(true);
var selectedMaterialChannelIndex = parentObjectMaterialDuplicate.MaterialChannelIndexFromId(doc.Materials[selectedDocMaterialIndex].Id, true);
var modifiedParentObjectMaterialIndex = doc.Materials.Add(parentObjectMaterialDuplicate);
// Apply the material to the BrepFace
rhinoObj.Attributes.MaterialIndex = modifiedParentObjectMaterialIndex;
rhinoObj.Attributes.MaterialSource = ObjectMaterialSource.MaterialFromObject; // Use material from parent
// apply the material channel index to the brepface
brep.Faces[brepFaceIndex].MaterialChannelIndex = selectedMaterialChannelIndex;
// Commit changes
rhinoObj.CommitChanges();
RhinoApp.WriteLine($"Material applied to BrepFace (index: {brepFaceIndex}).");
}
this works the first time i apply it to a new object of BrepObject type but it doesnt work when I use the command again to paint another face. It either applies the material to another face that I did not select or it does not apply any material to that face.
what can i do differently?
Thanks
Srujan