Materials: Child ignoring parent material
Inherit the material from the parent object when creating a new object, such as during a boolean operation, or when extruding a sketch. fixes #15503
This commit is contained in:
committed by
Yorik van Havre
parent
5435b3e4db
commit
0804d80ebf
@@ -86,7 +86,7 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
|
||||
TopoShape res(0);
|
||||
this->Shape.setValue(res.makeElementShape(mkChamfer,baseTopoShape,Part::OpCodes::Chamfer));
|
||||
return Part::Feature::execute();
|
||||
return Part::FilletBase::execute();
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
|
||||
@@ -69,6 +69,10 @@ App::DocumentObjectExecReturn *Compound::execute()
|
||||
}
|
||||
}
|
||||
this->Shape.setValue(TopoShape().makeElementCompound(shapes));
|
||||
if (Links.getSize() > 0) {
|
||||
App::DocumentObject* link = Links.getValues()[0];
|
||||
copyMaterial(link);
|
||||
}
|
||||
return Part::Feature::execute();
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
|
||||
@@ -90,7 +90,7 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
|
||||
TopoShape res(0);
|
||||
this->Shape.setValue(res.makeElementShape(mkFillet,baseTopoShape,Part::OpCodes::Fillet));
|
||||
return Part::Feature::execute();
|
||||
return Part::FilletBase::execute();
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
|
||||
@@ -257,6 +257,8 @@ App::DocumentObjectExecReturn *Mirroring::execute()
|
||||
if (shape.isNull())
|
||||
Standard_Failure::Raise("Cannot mirror empty shape");
|
||||
this->Shape.setValue(TopoShape(0).makeElementMirror(shape,ax2));
|
||||
copyMaterial(link);
|
||||
|
||||
return Part::Feature::execute();
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
|
||||
@@ -136,6 +136,7 @@ App::DocumentObjectExecReturn* Boolean::execute()
|
||||
res = res.makeElementRefine();
|
||||
}
|
||||
this->Shape.setValue(res);
|
||||
copyMaterial(base);
|
||||
return Part::Feature::execute();
|
||||
}
|
||||
catch (...) {
|
||||
|
||||
@@ -117,6 +117,10 @@ App::DocumentObjectExecReturn *MultiCommon::execute()
|
||||
res = res.makeElementRefine();
|
||||
}
|
||||
this->Shape.setValue(res);
|
||||
if (Shapes.getSize() > 0) {
|
||||
App::DocumentObject* link = Shapes.getValues()[0];
|
||||
copyMaterial(link);
|
||||
}
|
||||
|
||||
return Part::Feature::execute();
|
||||
}
|
||||
|
||||
@@ -208,6 +208,9 @@ App::DocumentObjectExecReturn *MultiFuse::execute()
|
||||
}
|
||||
this->Shape.setValue(res);
|
||||
this->History.setValues(history);
|
||||
|
||||
App::DocumentObject* link = Shapes.getValues()[0];
|
||||
copyMaterial(link);
|
||||
return Part::Feature::execute();
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
|
||||
@@ -128,6 +128,26 @@ PyObject *Feature::getPyObject()
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
|
||||
void Feature::copyMaterial(Feature* feature)
|
||||
{
|
||||
auto mat = Materials::MaterialManager::defaultMaterial();
|
||||
if (feature) {
|
||||
if (ShapeMaterial.getValue().getUUID() != feature->ShapeMaterial.getValue().getUUID()) {
|
||||
if (ShapeMaterial.getValue().getUUID() == mat->getUUID()) {
|
||||
ShapeMaterial.setValue(feature->ShapeMaterial.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Feature::copyMaterial(App::DocumentObject* link)
|
||||
{
|
||||
auto feature = dynamic_cast<Part::Feature*>(link);
|
||||
if (feature) {
|
||||
copyMaterial(feature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override getElementName to support the Export type. Other calls are passed to the original
|
||||
* method
|
||||
@@ -1709,6 +1729,16 @@ short FilletBase::mustExecute() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn* FilletBase::execute()
|
||||
{
|
||||
App::DocumentObject* link = this->Base.getValue();
|
||||
if (!link) {
|
||||
return new App::DocumentObjectExecReturn("No object linked");
|
||||
}
|
||||
copyMaterial(link);
|
||||
return Part::Feature::execute();
|
||||
}
|
||||
|
||||
void FilletBase::onChanged(const App::Property *prop) {
|
||||
if(getDocument() && !getDocument()->testStatus(App::Document::Restoring)) {
|
||||
if(prop == &Edges || prop == &Base) {
|
||||
|
||||
@@ -169,6 +169,9 @@ protected:
|
||||
void onBeforeChange(const App::Property* prop) override;
|
||||
void onChanged(const App::Property* prop) override;
|
||||
|
||||
void copyMaterial(Feature* feature);
|
||||
void copyMaterial(App::DocumentObject* link);
|
||||
|
||||
void registerElementCache(const std::string &prefix, PropertyPartShape *prop);
|
||||
|
||||
/** Helper function to obtain mapped and indexed element name from a shape
|
||||
@@ -210,7 +213,8 @@ public:
|
||||
App::PropertyLinkSub EdgeLinks;
|
||||
|
||||
short mustExecute() const override;
|
||||
void onUpdateElementReference(const App::Property *prop) override;
|
||||
App::DocumentObjectExecReturn* execute() override;
|
||||
void onUpdateElementReference(const App::Property* prop) override;
|
||||
|
||||
protected:
|
||||
void onDocumentRestored() override;
|
||||
|
||||
@@ -471,6 +471,20 @@ void Body::onChanged(const App::Property* prop) {
|
||||
}
|
||||
|
||||
}
|
||||
else if (prop == &ShapeMaterial) {
|
||||
std::vector<App::DocumentObject*> features = Group.getValues();
|
||||
if (!features.empty()) {
|
||||
for (auto it : features) {
|
||||
auto feature = dynamic_cast<Part::Feature*>(it);
|
||||
if (feature) {
|
||||
if (feature->ShapeMaterial.getValue().getUUID()
|
||||
!= ShapeMaterial.getValue().getUUID()) {
|
||||
feature->ShapeMaterial.setValue(ShapeMaterial.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Part::BodyBase::onChanged(prop);
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
# include <TopoDS.hxx>
|
||||
#endif
|
||||
|
||||
#include "App/OriginFeature.h"
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <App/ElementNamingUtils.h>
|
||||
#include "App/OriginFeature.h"
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <Base/Console.h>
|
||||
|
||||
#include "Feature.h"
|
||||
@@ -66,6 +66,8 @@ Feature::Feature()
|
||||
|
||||
App::DocumentObjectExecReturn* Feature::recompute()
|
||||
{
|
||||
setMaterialToBodyMaterial();
|
||||
|
||||
SuppressedShape.setValue(TopoShape());
|
||||
|
||||
if (!Suppressed.getValue()) {
|
||||
@@ -97,6 +99,18 @@ App::DocumentObjectExecReturn* Feature::recompute()
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
void Feature::setMaterialToBodyMaterial()
|
||||
{
|
||||
auto body = getFeatureBody();
|
||||
if (body) {
|
||||
// Ensure the part has the same material as the body
|
||||
auto feature = dynamic_cast<Part::Feature*>(body);
|
||||
if (feature) {
|
||||
copyMaterial(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Feature::updateSuppressedShape()
|
||||
{
|
||||
auto baseShape = getBaseTopoShape(true);
|
||||
@@ -166,6 +180,14 @@ void Feature::onChanged(const App::Property *prop)
|
||||
body->insertObject(BaseFeature.getValue(), this);
|
||||
}
|
||||
}
|
||||
} else if (prop == &ShapeMaterial) {
|
||||
auto body = Body::findBodyOf(this);
|
||||
if (body) {
|
||||
if (body->ShapeMaterial.getValue().getUUID()
|
||||
!= ShapeMaterial.getValue().getUUID()) {
|
||||
body->ShapeMaterial.setValue(ShapeMaterial.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Part::Feature::onChanged(prop);
|
||||
@@ -375,7 +397,7 @@ Body* Feature::getFeatureBody() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
App::DocumentObject *Feature::getSubObject(const char *subname,
|
||||
App::DocumentObject *Feature::getSubObject(const char *subname,
|
||||
PyObject **pyObj, Base::Matrix4D *pmat, bool transform, int depth) const
|
||||
{
|
||||
if (subname && subname != Data::findElementName(subname)) {
|
||||
@@ -400,7 +422,7 @@ App::DocumentObject *Feature::getSubObject(const char *subname,
|
||||
// an inverse transform.
|
||||
_mat = Placement.getValue().inverse().toMatrix();
|
||||
if (pmat)
|
||||
*pmat *= _mat;
|
||||
*pmat *= _mat;
|
||||
else
|
||||
pmat = &_mat;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,11 @@ protected:
|
||||
|
||||
void updateSuppressedShape();
|
||||
|
||||
/**
|
||||
* Set the Material To Body Material object
|
||||
*/
|
||||
void setMaterialToBodyMaterial();
|
||||
|
||||
/// Grab any point from the given face
|
||||
static const gp_Pnt getPointFromFace(const TopoDS_Face& f);
|
||||
/// Make a shape from a base plane (convenience method)
|
||||
|
||||
@@ -247,23 +247,11 @@ void ViewProviderBody::updateData(const App::Property* prop)
|
||||
static_cast<PartDesignGui::ViewProvider*>(vp)->setTipIcon(feature == tip);
|
||||
}
|
||||
}
|
||||
|
||||
if (tip)
|
||||
copyColorsfromTip(tip);
|
||||
}
|
||||
|
||||
PartGui::ViewProviderPart::updateData(prop);
|
||||
}
|
||||
|
||||
void ViewProviderBody::copyColorsfromTip(App::DocumentObject* tip) {
|
||||
// update ShapeAppearance
|
||||
Gui::ViewProvider* vptip = Gui::Application::Instance->getViewProvider(tip);
|
||||
if (vptip && vptip->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
|
||||
auto materials = static_cast<PartGui::ViewProviderPartExt*>(vptip)->ShapeAppearance.getValues();
|
||||
this->ShapeAppearance.setValues(materials);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderBody::slotChangedObjectApp ( const App::DocumentObject& obj, const App::Property& prop ) {
|
||||
|
||||
if(App::GetApplication().isRestoring())
|
||||
|
||||
@@ -97,9 +97,6 @@ protected:
|
||||
/// Set Feature viewprovider into visual body mode
|
||||
void setVisualBodyMode(bool bodymode);
|
||||
|
||||
private:
|
||||
void copyColorsfromTip(App::DocumentObject* tip);
|
||||
|
||||
private:
|
||||
static const char* BodyModeEnum[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user