to repace it.but it don’t work .When i put it into my material use: material.AddTexture(tex);
there were appear a black with nothing picture.
How can I add picture into Rhino?
Is my understanding wrong? texture is under material.
Or there have other way to put my own picture into rhino attribute to become my material or decals or anything.
I get the object which has bitmap texture and the file name is A11.jpg.
I try to set the bitmap texture which file name is A12.jpg to the object by coding.
I check the object on Rhino material,the name of bitmap texture is still A11.jpg
This is needed because above, you are copying the original material with this code:
ON_Material material = object->ObjectMaterial();
However, even after making this change, it would not work properly because you are directly manipulating the document material table. Although this used to work back in the days before there was a Material Editor, it won’t fully work now because the Material Editor won’t update. Therefore, I recommend the following approach which operates at a higher level and ensures that everything updates. Behind the scenes this will still do what your code does, but it will also allow the Material Editor to update:
unsigned int geometry_filter =
CRhinoGetObject::surface_object |
CRhinoGetObject::polysrf_object |
CRhinoGetObject::mesh_object;
CRhinoGetObject go;
go.SetCommandPrompt(L"Select surface, polysurface, or mesh to modify texture");
go.SetGeometryFilter(geometry_filter);
go.EnablePreSelect(TRUE);
go.EnableSubObjectSelect(FALSE);
go.GetObjects(1, 1);
if (go.CommandResult() != CRhinoCommand::success)
return go.CommandResult();
const CRhinoObjRef& object_ref = go.Object(0);
const CRhinoObject* object = object_ref.Object();
if (0 == object)
return CRhinoCommand::failure;
ON_Material material = object->ObjectMaterial();
int ti = material.FindTexture(0, ON_Texture::TYPE::bitmap_texture);
if (ti >= 0) {
CRhinoGetFileDialog gf1;
gf1.SetScriptMode(context.IsInteractive() ? FALSE : TRUE);
BOOL bResult = gf1.DisplayFileDialog(CRhinoGetFileDialog::open_bitmap_dialog);
if (!bResult)
return CRhinoCommand::cancel;
ON_wString found_file_full_path = gf1.FileName();
auto& doc = context.m_doc;
// This is where the procedure is different. We use the RDK SDK instead of the pure Rhino SDK
// to make sure that the Material Editor also updates. This also ensures that undo will restore
// the material to its previous state.
// Find the RDK material.
auto* pMaterial = doc.Contents().Find(material.RdkMaterialInstanceId());
if (pMaterial == nullptr)
return CRhinoCommand::failure;
// Find the material's child bitmap texture.
const auto* pChild = pMaterial->FindChild(CS_MAT_BITMAP_TEXTURE);
if (pChild == nullptr)
return CRhinoCommand::failure;
// Make the operation undoable.
CRhRdkContentUndo cu(doc);
cu.ModifyContent(*pMaterial);
// Begin the change operation.
auto& child = pChild->BeginChange(RhRdkChangeContext::Program);
// Get the child's file-based interface and set the file name.
auto* pFileBased = dynamic_cast<IRhRdkFileBasedContent*>(&child);
if (pFileBased != nullptr)
pFileBased->SetFilename(found_file_full_path);
// Set the name of the material from the file name.
ON_wString sName;
ON_FileSystemPath::SplitPath(found_file_full_path, nullptr, nullptr, &sName, nullptr);
child.SetInstanceName(sName);
// End the change operation.
child.EndChange();
doc.DeferredRedraw();
}
I hope this does what you need. Please let me know if you have any further questions.
I’m sorry, I should not have told you to use IRhRdkFileBasedContent because it’s a very recent addition. and only works in the very latest Rhino 7. The best way to do this so it works in 6 and 7 is like this:
I found the texture of the object changes on the Viewport but I check the object on Rhino material,
the name of bitmap texture does not change.
That’s because you need to use the new RDK code. The pure Rhino code does not know how to update the Material Editor (which includes any view of the material).
For completeness, the following is the exact code that you should need to get this working the way you want in Rhino 6 and Rhino 7:
unsigned int geometry_filter =
CRhinoGetObject::surface_object |
CRhinoGetObject::polysrf_object |
CRhinoGetObject::mesh_object;
CRhinoGetObject go;
go.SetCommandPrompt(L"Select surface, polysurface, or mesh to modify texture");
go.SetGeometryFilter(geometry_filter);
go.EnablePreSelect(TRUE);
go.EnableSubObjectSelect(FALSE);
go.GetObjects(1, 1);
if (go.CommandResult() != CRhinoCommand::success)
return go.CommandResult();
const CRhinoObjRef& object_ref = go.Object(0);
const CRhinoObject* object = object_ref.Object();
if (0 == object)
return CRhinoCommand::failure;
ON_Material material = object->ObjectMaterial();
int ti = material.FindTexture(0, ON_Texture::TYPE::bitmap_texture);
if (ti >= 0) {
CRhinoGetFileDialog gf1;
gf1.SetScriptMode(context.IsInteractive() ? FALSE : TRUE);
BOOL bResult = gf1.DisplayFileDialog(CRhinoGetFileDialog::open_bitmap_dialog);
if (!bResult)
return CRhinoCommand::cancel;
ON_wString found_file_full_path = gf1.FileName();
auto& doc = context.m_doc;
// This is where the procedure is different. We use the RDK SDK instead of the pure Rhino SDK
// to make sure that the Material Editor also updates. This also ensures that undo will restore
// the material to its previous state.
// Find the RDK material.
auto* pMaterial = doc.Contents().Find(material.RdkMaterialInstanceId());
if (pMaterial == nullptr)
return CRhinoCommand::failure;
// Find the material's child bitmap texture.
const auto* pChild = pMaterial->FindChild(CS_MAT_BITMAP_TEXTURE);
if (pChild == nullptr)
return CRhinoCommand::failure;
// Make the operation undoable.
CRhRdkContentUndo cu(doc);
cu.ModifyContent(*pMaterial);
// Begin the change operation.
auto& child = pChild->BeginChange(RhRdkChangeContext::Program);
// Set the child texture's file name.
const wchar_t* filename = found_file_full_path;
child.SetParameter(FS_TEX_FILENAME, filename);
// Set the name of the material from the file name.
ON_wString sName;
ON_FileSystemPath::SplitPath(found_file_full_path, nullptr, nullptr, &sName, nullptr);
child.SetInstanceName(sName);
// End the change operation.
child.EndChange();
doc.DeferredRedraw();
}
The name of the material will not change because we are only setting the name of the texture. I see I have written the comment wrong. It should say:
// Set the name of the texture from the file name.
ON_wString sName;
ON_FileSystemPath::SplitPath(found_file_full_path, nullptr, nullptr, &sName, nullptr);
child.SetInstanceName(sName);
Sorry about that.
If you want the material name to change as well, you can add this line:
pMaterial->SetInstanceName(sName);
I can help you with the compiler error – please copy and paste the error message here.
After compile the project, you can
Step1. Load DESSample plugin
Step2. On Rendered mode, drawing rectangular plane surface.
Step3. Run SampleTexture on Rhino command prompt
Step4. Click the rectangular plane surface
Step5. Click the option “material” on Rhino command prompt
Step6. it issue dialog box
You can set attribute or material to the object.
In the CDlgSampleTexture::UpdateObj(), I have several conditions,
// There are no attribute and material on the object
// So it want to add attribute and material which no bitmap texture to the object
// it want to modify the color and name of the attribute and material to the object
// the object has material which no bitmap texture, so it want to add bitmap texture the object
// or modify bitmap texture on the material
// or delete bitmap texture from the material, but keep the color and name of attribute and material on the object.
PS: If turn off the check box of Texture, the path of the Bitmap will be cleared.
If turn on the check box of Texture, you can select picture by click “…” button
In the condition 1 and 2, I write several code, but I’m not sure if is correct and I still use old way.
In the condition 3, I need to you help me , because I don’t know to write the program.
Until now, we always use old way to set attribute and material, now we have big problem to add texture and modify texture. It is very unstable.
For new way, I can not use clearly and I feel confuse.
I have updated your code and attached the changed file (DlgSampleTexture.cpp) as a zip. I had to reorganize the UpdateObj() function a bit to make it easier to add the new code. I also added some notes about what the code is doing. I hope this does what you need. If you have any further questions, I’d be happy to try and help.