I’m attempting to assign materials directly to brepFaces. I can’t find any methods that fit, and feel like I’ve looked everywhere: the object, the face, and everything in between. Is it simply not possible without exploding it into a polymesh, and assigning on a per-object basis?
As far as I can read the C++ sample, you add a channel to the material, then select that channel on the brepFace. In C# there is nothing called anything with material or channel on brepfaces that I can see. I also can’t see channels being present on materials but maybe I’m looking in the wrong place.
Hi @Jussi_Aaltonen ,
I am trying to do something similar but instead of using ActiveDoc.Materials, I am using Render.RenderMaterials as I wish to use materials that have not been added to objects yet but are still available in the library. any solutions to apply RenderMaterial to a brepFace instead?
As far as I know you need to add the material to the document before you can use it as brep face material. I’m trying to find someone with more insight to this.
You also need a Material in RhinoDoc.Materials referencing each RenderMaterial. Then you can set up the brep face materials just like in the example. I need to check how to create those Materials correctly.
thanks for getting back.
I added the materials with proper material channels as shown in the example.
I am trying to achieve a PaintBucket style command where I will be able to select N number of subelements (also accepts entire objects which works fine but right now I am concerned about subelements).
Each subelement could belong to a different brep.
And i want to apply a selected material to those brep faces only.
// Loop through all selected objects
for (int i = 0; i < gs.ObjectCount; i++)
{
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 = objRef.Brep();
if (brep == null) continue;
// Get the face index from the selected component
int brepFaceIndex = objRef.GeometryComponentIndex.Index;
BrepFace brepFace = brep.Faces[brepFaceIndex];
var parentObjMaterialIndex = rhinoObj.Attributes.MaterialIndex;
var parentObjectMaterial = new Material(doc.Materials[parentObjMaterialIndex]);
// default channel index
int selectedMaterialChannelIndex = -1;
// check if renderMaterial exists in the doc.Materials table or else add the material
var selectedDocMaterial = doc.Materials.FirstOrDefault(docMat => docMat.Id == selectedRenderMaterial.Id);
var selectedDocMaterialIndex = selectedDocMaterial == null ? doc.Materials.Add(selectedRenderMaterial.ToMaterial(RenderTexture.TextureGeneration.Allow)) : selectedDocMaterial.Index;
selectedMaterialChannelIndex = parentObjectMaterial.MaterialChannelIndexFromId(doc.Materials[selectedDocMaterialIndex].Id, true);
var modifiedParentObjectMaterialIndex = doc.Materials.Add(parentObjectMaterial);
// 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
brepFace.MaterialChannelIndex = selectedMaterialChannelIndex;
// Commit changes
RhinoApp.WriteLine($"Material applied to BrepFace (index: {brepFaceIndex}).");
}
else
{
// Apply material to the entire object
rhinoObj.Attributes.MaterialSource = ObjectMaterialSource.MaterialFromObject;
rhinoObj.Attributes.RenderMaterial = selectedRenderMaterial;
}
rhinoObj.CommitChanges();
}
this does not work yet but its a start. I was hoping to understand how to apply materials to individual brep faces regardless of if they belonged to single or multiple breps.