fixes #0003582: ShapeBinder did not show correctly

This commit is contained in:
wmayer
2018-09-22 00:55:46 +02:00
parent b129511910
commit b3795b7579
2 changed files with 73 additions and 22 deletions

View File

@@ -23,11 +23,13 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <cfloat>
#include <cfloat>
#include <boost/bind.hpp>
#include <BRepBuilderAPI_MakeFace.hxx>
#endif
#include "ShapeBinder.h"
#include <App/Document.h>
#include <Mod/Part/App/TopoShape.h>
#ifndef M_PI
@@ -44,15 +46,19 @@ ShapeBinder::ShapeBinder()
{
ADD_PROPERTY_TYPE(Support, (0,0), "",(App::PropertyType)(App::Prop_None),"Support of the geometry");
Placement.setStatus(App::Property::Hidden, true);
ADD_PROPERTY_TYPE(TraceSupport, (false), "", App::Prop_None, "Trace support shape");
}
ShapeBinder::~ShapeBinder()
{
this->connectDocumentChangedObject.disconnect();
}
short int ShapeBinder::mustExecute(void) const {
if(Support.isTouched())
if (Support.isTouched())
return 1;
if (TraceSupport.isTouched())
return 1;
return Part::Feature::mustExecute();
@@ -60,16 +66,29 @@ short int ShapeBinder::mustExecute(void) const {
App::DocumentObjectExecReturn* ShapeBinder::execute(void) {
if(! this->isRestoring()){
if (!this->isRestoring()) {
Part::Feature* obj = nullptr;
std::vector<std::string> subs;
ShapeBinder::getFilteredReferences(&Support, obj, subs);
//if we have a link we rebuild the shape, but we change nothing if we are a simple copy
if(obj) {
if (obj) {
Part::TopoShape shape = ShapeBinder::buildShapeFromReferences(obj, subs);
Base::Placement placement(shape.getTransform());
Shape.setValue(shape);
if (TraceSupport.getValue()) {
chain.clear();
std::vector<App::DocumentObject*> list = getInListRecursive();
chain.insert(chain.end(), list.begin(), list.end());
list = obj->getInListRecursive();
chain.insert(chain.end(), list.begin(), list.end());
// this is the inverted global placement of the parent group ...
placement = this->globalPlacement() * Placement.getValue().inverse();
// multiplied with the global placement of the support shape
placement = placement.inverse() * obj->globalPlacement();
}
Placement.setValue(placement);
}
}
@@ -77,76 +96,75 @@ App::DocumentObjectExecReturn* ShapeBinder::execute(void) {
return Part::Feature::execute();
}
void ShapeBinder::getFilteredReferences(App::PropertyLinkSubList* prop, Part::Feature*& obj, std::vector< std::string >& subobjects) {
void ShapeBinder::getFilteredReferences(App::PropertyLinkSubList* prop, Part::Feature*& obj,
std::vector< std::string >& subobjects)
{
obj = nullptr;
subobjects.clear();
auto objs = prop->getValues();
auto subs = prop->getSubValues();
if(objs.empty()) {
if (objs.empty()) {
return;
}
//we only allow one part feature, so get the first one we find
size_t index = 0;
while(index < objs.size() && !objs[index]->isDerivedFrom(Part::Feature::getClassTypeId()))
while (index < objs.size() && !objs[index]->isDerivedFrom(Part::Feature::getClassTypeId()))
index++;
//do we have any part feature?
if(index >= objs.size())
if (index >= objs.size())
return;
obj = static_cast<Part::Feature*>(objs[index]);
//if we have no subshpape we use the whole shape
if(subs[index].empty()) {
return;
if (subs[index].empty()) {
return;
}
//collect all subshapes for the object
index = 0;
for(std::string sub : subs) {
for (std::string sub : subs) {
//we only allow subshapes from a single Part::Feature
if(objs[index] != obj)
if (objs[index] != obj)
continue;
//in this mode the full shape is not allowed, as we already started the subshape
//processing
if(sub.empty())
if (sub.empty())
continue;
subobjects.push_back(sub);
}
}
Part::TopoShape ShapeBinder::buildShapeFromReferences( Part::Feature* obj, std::vector< std::string > subs) {
if(!obj)
if (!obj)
return TopoDS_Shape();
if(subs.empty())
if (subs.empty())
return obj->Shape.getShape();
//if we use multiple subshapes we build a shape from them by fusing them together
Part::TopoShape base;
std::vector<TopoDS_Shape> operators;
for(std::string sub : subs) {
if(base.isNull())
for (std::string sub : subs) {
if (base.isNull())
base = obj->Shape.getShape().getSubShape(sub.c_str());
else
operators.push_back(obj->Shape.getShape().getSubShape(sub.c_str()));
}
try {
if(!operators.empty() && !base.isNull())
if (!operators.empty() && !base.isNull())
return base.fuse(operators);
}
catch(...) {
catch (...) {
return base;
}
return base;
@@ -159,3 +177,26 @@ void ShapeBinder::handleChangedPropertyType(Base::XMLReader &reader, const char
Support.Restore(reader);
}
}
void ShapeBinder::onSettingDocument()
{
App::Document* document = getDocument();
if (document) {
this->connectDocumentChangedObject = document->signalChangedObject.connect(boost::bind
(&ShapeBinder::slotChangedObject, this, _1, _2));
}
}
void ShapeBinder::slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop)
{
if (this == &Obj)
return;
if (!TraceSupport.getValue())
return;
if (!Prop.getTypeId().isDerivedFrom(App::PropertyPlacement::getClassTypeId()))
return;
auto it = std::find(chain.begin(), chain.end(), &Obj);
if (it != chain.end()) {
touch();
}
}

View File

@@ -25,6 +25,7 @@
#define PARTDESIGN_DATUMSHAPE_H
#include <QString>
#include <boost/signals.hpp>
#include <App/PropertyLinks.h>
#include <Mod/Part/App/DatumFeature.h>
@@ -48,6 +49,7 @@ public:
virtual ~ShapeBinder();
App::PropertyLinkSubListGlobal Support;
App::PropertyBool TraceSupport;
static void getFilteredReferences(App::PropertyLinkSubList* prop, Part::Feature*& object, std::vector< std::string >& subobjects);
static Part::TopoShape buildShapeFromReferences(Feature* obj, std::vector< std::string > subs);
@@ -60,6 +62,14 @@ protected:
virtual void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop);
virtual short int mustExecute(void) const;
virtual App::DocumentObjectExecReturn* execute(void);
private:
void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop);
virtual void onSettingDocument();
std::vector<App::DocumentObject*> chain;
typedef boost::signals::connection Connection;
Connection connectDocumentChangedObject;
};
} //namespace PartDesign