TechDraw: Link related changes

* Support link and group objects

* Support view sync by implementing view provider API getMDIView()

* Use handleChangedPropertyType() for object migration instead of
  reimplementing Restore() because of a lots of changes in
  PropertyContainer::Restore().

* Various other small fixes.
This commit is contained in:
Zheng, Lei
2019-07-12 11:28:07 +08:00
committed by wmayer
parent f028ba42ff
commit e90d09dc40
30 changed files with 204 additions and 412 deletions

View File

@@ -308,11 +308,13 @@ private:
try {
EdgeWalker ew;
ew.loadEdges(edgeList);
success = ew.perform();
if (success) {
if(ew.perform()) {
std::vector<TopoDS_Wire> rw = ew.getResultNoDups();
std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(rw,true);
outerWire = new TopoShapeWirePy(new TopoShape(*sortedWires.begin()));
if(sortedWires.size()) {
outerWire = new TopoShapeWirePy(new TopoShape(*sortedWires.begin()));
success = true;
}
} else {
Base::Console().Warning("ATDP::findShapeOutline: input is not planar graph. Wire detection not done\n");
}
@@ -461,6 +463,8 @@ private:
void write1ViewDxf( ImpExpDxfWrite& writer, TechDraw::DrawViewPart* dvp, bool alignPage)
{
if(!dvp->hasGeometry())
return;
TechDraw::GeometryObject* go = dvp->getGeometryObject();
TopoDS_Shape s = TechDraw::mirrorShape(go->getVisHard());
double offX = 0.0;

View File

@@ -80,7 +80,7 @@ DrawPage::DrawPage(void)
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
bool autoUpdate = hGrp->GetBool("KeepPagesUpToDate", 1l);
ADD_PROPERTY_TYPE(KeepUpdated, (autoUpdate), group, (App::PropertyType)(App::Prop_None), "Keep page in sync with model");
ADD_PROPERTY_TYPE(KeepUpdated, (autoUpdate), group, (App::PropertyType)(App::Prop_Output), "Keep page in sync with model");
ADD_PROPERTY_TYPE(Template, (0), group, (App::PropertyType)(App::Prop_None), "Attached Template");
Template.setScope(App::LinkScope::Global);
ADD_PROPERTY_TYPE(Views, (0), group, (App::PropertyType)(App::Prop_None), "Attached Views");
@@ -417,68 +417,26 @@ int DrawPage::getNextBalloonIndex(void)
return result;
}
void DrawPage::Restore(Base::XMLReader &reader)
void DrawPage::handleChangedPropertyType(
Base::XMLReader &reader, const char * TypeName, App::Property * prop)
{
reader.readElement("Properties");
int Cnt = reader.getAttributeAsInteger("Count");
for (int i=0 ;i<Cnt ;i++) {
reader.readElement("Property");
const char* PropName = reader.getAttribute("name");
const char* TypeName = reader.getAttribute("type");
App::Property* schemaProp = getPropertyByName(PropName);
try {
if(schemaProp){
if (strcmp(schemaProp->getTypeId().getName(), TypeName) == 0){ //if the property type in obj == type in schema
schemaProp->Restore(reader); //nothing special to do
} else {
if (strcmp(PropName, "Scale") == 0) {
if (schemaProp->isDerivedFrom(App::PropertyFloatConstraint::getClassTypeId())){ //right property type
schemaProp->Restore(reader); //nothing special to do
} else { //Scale, but not PropertyFloatConstraint
App::PropertyFloat tmp;
if (strcmp(tmp.getTypeId().getName(),TypeName)) { //property in file is Float
tmp.setContainer(this);
tmp.Restore(reader);
double tmpValue = tmp.getValue();
if (tmpValue > 0.0) {
static_cast<App::PropertyFloatConstraint*>(schemaProp)->setValue(tmpValue);
} else {
static_cast<App::PropertyFloatConstraint*>(schemaProp)->setValue(1.0);
}
} else {
// has Scale prop that isn't Float!
Base::Console().Log("DrawPage::Restore - old Document Scale is Not Float!\n");
// no idea
}
}
} else {
Base::Console().Log("DrawPage::Restore - old Document has unknown Property\n");
}
}
if (prop == &Scale) {
App::PropertyFloat tmp;
if (strcmp(tmp.getTypeId().getName(),TypeName)==0) { //property in file is Float
tmp.setContainer(this);
tmp.Restore(reader);
double tmpValue = tmp.getValue();
if (tmpValue > 0.0) {
Scale.setValue(tmpValue);
} else {
Scale.setValue(1.0);
}
} else {
// has Scale prop that isn't Float!
Base::Console().Log("DrawPage::Restore - old Document Scale is Not Float!\n");
// no idea
}
catch (const Base::XMLParseException&) {
throw; // re-throw
}
catch (const Base::Exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const std::exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const char* e) {
Base::Console().Error("%s\n", e);
}
#ifndef FC_DEBUG
catch (...) {
Base::Console().Error("PropertyContainer::Restore: Unknown C++ exception thrown\n");
}
#endif
reader.readEndElement("Property");
}
reader.readEndElement("Properties");
}
// Python Drawing feature ---------------------------------------------------------

View File

@@ -57,7 +57,8 @@ public:
/// recalculate the Feature
virtual App::DocumentObjectExecReturn *execute(void);
//@}
void Restore(Base::XMLReader &reader);
virtual void handleChangedPropertyType(
Base::XMLReader &reader, const char * TypeName, App::Property * prop) override;
int addView(App::DocumentObject *docObj);
int removeView(App::DocumentObject* docObj);

View File

@@ -174,7 +174,10 @@ App::DocumentObjectExecReturn *DrawProjGroup::execute(void)
// }
for (auto& item: getViewsAsDPGI()) {
bool touched = item->isTouched();
item->autoPosition();
if(!touched)
item->purgeTouched();
}
return DrawViewCollection::execute();
@@ -427,7 +430,6 @@ App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType)
Anchor.purgeTouched();
view->LockPosition.setValue(true); //lock "Front" position within DPG (note not Page!).
view->LockPosition.setStatus(App::Property::ReadOnly,true); //Front should stay locked.
App::GetApplication().signalChangePropertyEditor(view->LockPosition);
view->LockPosition.purgeTouched();
requestPaint(); //make sure the group object is on the Gui page
}

View File

@@ -84,6 +84,9 @@ using namespace TechDraw;
boost::match_flag_type flags = boost::match_default;
// char* endChar;
std::string::const_iterator begin = geomName.begin();
auto pos = geomName.rfind('.');
if(pos!=std::string::npos)
begin += pos+1;
std::string::const_iterator end = geomName.end();
std::stringstream ErrorMsg;
@@ -106,6 +109,9 @@ std::string DrawUtil::getGeomTypeFromName(std::string geomName)
boost::match_results<std::string::const_iterator> what;
boost::match_flag_type flags = boost::match_default;
std::string::const_iterator begin = geomName.begin();
auto pos = geomName.rfind('.');
if(pos!=std::string::npos)
begin += pos+1;
std::string::const_iterator end = geomName.end();
std::stringstream ErrorMsg;

View File

@@ -121,7 +121,6 @@ void DrawView::onChanged(const App::Property* prop)
auto page = findParentPage();
if (ScaleType.isValue("Page")) {
Scale.setStatus(App::Property::ReadOnly,true);
App::GetApplication().signalChangePropertyEditor(Scale);
if (page != nullptr) {
if(std::abs(page->Scale.getValue() - getScale()) > FLT_EPSILON) {
Scale.setValue(page->Scale.getValue());
@@ -131,10 +130,8 @@ void DrawView::onChanged(const App::Property* prop)
} else if ( ScaleType.isValue("Custom") ) {
//don't change Scale
Scale.setStatus(App::Property::ReadOnly,false);
App::GetApplication().signalChangePropertyEditor(Scale);
} else if ( ScaleType.isValue("Automatic") ) {
Scale.setStatus(App::Property::ReadOnly,true);
App::GetApplication().signalChangePropertyEditor(Scale);
if (!checkFit(page)) {
double newScale = autoScale(page->getPageWidth(),page->getPageHeight());
if(std::abs(newScale - getScale()) > FLT_EPSILON) { //stops onChanged/execute loop
@@ -162,23 +159,19 @@ void DrawView::handleXYLock(void)
if (isLocked()) {
if (!X.testStatus(App::Property::ReadOnly)) {
X.setStatus(App::Property::ReadOnly,true);
App::GetApplication().signalChangePropertyEditor(X);
X.purgeTouched();
}
if (!Y.testStatus(App::Property::ReadOnly)) {
Y.setStatus(App::Property::ReadOnly,true);
App::GetApplication().signalChangePropertyEditor(Y);
Y.purgeTouched();
}
} else {
if (X.testStatus(App::Property::ReadOnly)) {
X.setStatus(App::Property::ReadOnly,false);
App::GetApplication().signalChangePropertyEditor(X);
X.purgeTouched();
}
if (Y.testStatus(App::Property::ReadOnly)) {
Y.setStatus(App::Property::ReadOnly,false);
App::GetApplication().signalChangePropertyEditor(Y);
Y.purgeTouched();
}
}
@@ -327,93 +320,46 @@ std::vector<TechDraw::DrawLeaderLine*> DrawView::getLeaders() const
return result;
}
void DrawView::Restore(Base::XMLReader &reader)
void DrawView::handleChangedPropertyType(
Base::XMLReader &reader, const char * TypeName, App::Property * prop)
{
// this is temporary code for backwards compat (within v0.17). can probably be deleted once there are no development
// fcstd files with old property types in use.
reader.readElement("Properties");
int Cnt = reader.getAttributeAsInteger("Count");
for (int i=0 ;i<Cnt ;i++) {
reader.readElement("Property");
const char* PropName = reader.getAttribute("name");
const char* TypeName = reader.getAttribute("type");
App::Property* schemaProp = getPropertyByName(PropName);
try {
if(schemaProp){
if (strcmp(schemaProp->getTypeId().getName(), TypeName) == 0){ //if the property type in obj == type in schema
schemaProp->Restore(reader); //nothing special to do
} else {
if (strcmp(PropName, "Scale") == 0) {
if (schemaProp->isDerivedFrom(App::PropertyFloatConstraint::getClassTypeId())){ //right property type
schemaProp->Restore(reader); //nothing special to do (redundant)
} else { //Scale, but not PropertyFloatConstraint
App::PropertyFloat tmp;
if (strcmp(tmp.getTypeId().getName(),TypeName)) { //property in file is Float
tmp.setContainer(this);
tmp.Restore(reader);
double tmpValue = tmp.getValue();
if (tmpValue > 0.0) {
static_cast<App::PropertyFloatConstraint*>(schemaProp)->setValue(tmpValue);
} else {
static_cast<App::PropertyFloatConstraint*>(schemaProp)->setValue(1.0);
}
} else {
// has Scale prop that isn't Float!
Base::Console().Log("DrawView::Restore - old Document Scale is Not Float!\n");
// no idea
}
}
} else if (strcmp(PropName, "Source") == 0) {
App::PropertyLinkGlobal glink;
App::PropertyLink link;
if (strcmp(glink.getTypeId().getName(),TypeName) == 0) { //property in file is plg
glink.setContainer(this);
glink.Restore(reader);
if (glink.getValue() != nullptr) {
static_cast<App::PropertyLinkList*>(schemaProp)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLinkList*>(schemaProp)->setValue(glink.getValue());
}
} else if (strcmp(link.getTypeId().getName(),TypeName) == 0) { //property in file is pl
link.setContainer(this);
link.Restore(reader);
if (link.getValue() != nullptr) {
static_cast<App::PropertyLinkList*>(schemaProp)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLinkList*>(schemaProp)->setValue(link.getValue());
}
} else {
// has Source prop isn't PropertyLink or PropertyLinkGlobal!
Base::Console().Log("DrawView::Restore - old Document Source is weird: %s\n", TypeName);
// no idea
}
} else {
Base::Console().Log("DrawView::Restore - old Document has unknown Property\n");
}
}
if (prop == &Scale) {
App::PropertyFloat tmp;
if (strcmp(tmp.getTypeId().getName(),TypeName)==0) { //property in file is Float
tmp.setContainer(this);
tmp.Restore(reader);
double tmpValue = tmp.getValue();
if (tmpValue > 0.0) {
Scale.setValue(tmpValue);
} else {
Scale.setValue(1.0);
}
} else {
// has Scale prop that isn't Float!
Base::Console().Log("DrawPage::Restore - old Document Scale is Not Float!\n");
// no idea
}
} else if (prop->isDerivedFrom(App::PropertyLinkList::getClassTypeId())
&& strcmp(prop->getName(),"Source")==0)
{
App::PropertyLinkGlobal glink;
App::PropertyLink link;
if (strcmp(glink.getTypeId().getName(),TypeName) == 0) { //property in file is plg
glink.setContainer(this);
glink.Restore(reader);
if (glink.getValue() != nullptr) {
static_cast<App::PropertyLinkList*>(prop)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLinkList*>(prop)->setValue(glink.getValue());
}
} else if (strcmp(link.getTypeId().getName(),TypeName) == 0) { //property in file is pl
link.setContainer(this);
link.Restore(reader);
if (link.getValue() != nullptr) {
static_cast<App::PropertyLinkList*>(prop)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLinkList*>(prop)->setValue(link.getValue());
}
}
catch (const Base::XMLParseException&) {
throw; // re-throw
}
catch (const Base::Exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const std::exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const char* e) {
Base::Console().Error("%s\n", e);
}
#ifndef FC_DEBUG
catch (...) {
Base::Console().Error("PropertyContainer::Restore: Unknown C++ exception thrown\n");
}
#endif
reader.readEndElement("Property");
}
reader.readEndElement("Properties");
}
bool DrawView::keepUpdated(void)

View File

@@ -67,7 +67,8 @@ public:
virtual void onDocumentRestored() override;
virtual short mustExecute() const override;
//@}
void Restore(Base::XMLReader &reader) override;
virtual void handleChangedPropertyType(
Base::XMLReader &reader, const char * TypeName, App::Property * prop) override;
bool isInClip();
DrawViewClip* getClipGroup(void);

View File

@@ -146,72 +146,3 @@ std::string DrawViewArch::getSVGTail(void)
std::string tail = "\\n</svg>";
return tail;
}
//DVA is still Source PropertyLink so needs different logic vs DV::Restore
void DrawViewArch::Restore(Base::XMLReader &reader)
{
// this is temporary code for backwards compat (within v0.17). can probably be deleted once there are no development
// fcstd files with old property types in use.
reader.readElement("Properties");
int Cnt = reader.getAttributeAsInteger("Count");
for (int i=0 ;i<Cnt ;i++) {
reader.readElement("Property");
const char* PropName = reader.getAttribute("name");
const char* TypeName = reader.getAttribute("type");
App::Property* schemaProp = getPropertyByName(PropName);
try {
if(schemaProp){
if (strcmp(schemaProp->getTypeId().getName(), TypeName) == 0){ //if the property type in obj == type in schema
schemaProp->Restore(reader); //nothing special to do
} else if (strcmp(PropName, "Source") == 0) {
App::PropertyLinkGlobal glink;
App::PropertyLink link;
if (strcmp(glink.getTypeId().getName(),TypeName) == 0) { //property in file is plg
glink.setContainer(this);
glink.Restore(reader);
if (glink.getValue() != nullptr) {
static_cast<App::PropertyLink*>(schemaProp)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLink*>(schemaProp)->setValue(glink.getValue());
}
} else if (strcmp(link.getTypeId().getName(),TypeName) == 0) { //property in file is pl
link.setContainer(this);
link.Restore(reader);
if (link.getValue() != nullptr) {
static_cast<App::PropertyLink*>(schemaProp)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLink*>(schemaProp)->setValue(link.getValue());
}
} else {
// has Source prop isn't PropertyLink or PropertyLinkGlobal!
Base::Console().Log("DrawViewArch::Restore - old Document Source is weird: %s\n", TypeName);
// no idea
}
} else {
Base::Console().Log("DrawViewArch::Restore - old Document has unknown Property\n");
}
}
}
catch (const Base::XMLParseException&) {
throw; // re-throw
}
catch (const Base::Exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const std::exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const char* e) {
Base::Console().Error("%s\n", e);
}
#ifndef FC_DEBUG
catch (...) {
Base::Console().Error("PropertyContainer::Restore: Unknown C++ exception thrown\n");
}
#endif
reader.readEndElement("Property");
}
reader.readEndElement("Properties");
}

View File

@@ -66,8 +66,6 @@ public:
virtual short mustExecute() const override;
void Restore(Base::XMLReader &reader) override;
protected:
/* virtual void onChanged(const App::Property* prop) override;*/

View File

@@ -143,75 +143,6 @@ std::string DrawViewDraft::getSVGTail(void)
return tail;
}
//DVD is still compatible with old Source PropertyLink so doesn't need DV::Restore logic
void DrawViewDraft::Restore(Base::XMLReader &reader)
{
// this is temporary code for backwards compat (within v0.17). can probably be deleted once there are no development
// fcstd files with old property types in use.
reader.readElement("Properties");
int Cnt = reader.getAttributeAsInteger("Count");
for (int i=0 ;i<Cnt ;i++) {
reader.readElement("Property");
const char* PropName = reader.getAttribute("name");
const char* TypeName = reader.getAttribute("type");
App::Property* schemaProp = getPropertyByName(PropName);
try {
if(schemaProp){
if (strcmp(schemaProp->getTypeId().getName(), TypeName) == 0){ //if the property type in obj == type in schema
schemaProp->Restore(reader); //nothing special to do
} else if (strcmp(PropName, "Source") == 0) {
App::PropertyLinkGlobal glink;
App::PropertyLink link;
if (strcmp(glink.getTypeId().getName(),TypeName) == 0) { //property in file is plg
glink.setContainer(this);
glink.Restore(reader);
if (glink.getValue() != nullptr) {
static_cast<App::PropertyLink*>(schemaProp)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLink*>(schemaProp)->setValue(glink.getValue());
}
} else if (strcmp(link.getTypeId().getName(),TypeName) == 0) { //property in file is pl
link.setContainer(this);
link.Restore(reader);
if (link.getValue() != nullptr) {
static_cast<App::PropertyLink*>(schemaProp)->setScope(App::LinkScope::Global);
static_cast<App::PropertyLink*>(schemaProp)->setValue(link.getValue());
}
} else {
// has Source prop isn't PropertyLink or PropertyLinkGlobal!
Base::Console().Log("DrawViewDraft::Restore - old Document Source is weird: %s\n", TypeName);
// no idea
}
} else {
Base::Console().Log("DrawViewDraft::Restore - old Document has unknown Property\n");
}
}
}
catch (const Base::XMLParseException&) {
throw; // re-throw
}
catch (const Base::Exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const std::exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const char* e) {
Base::Console().Error("%s\n", e);
}
#ifndef FC_DEBUG
catch (...) {
Base::Console().Error("PropertyContainer::Restore: Unknown C++ exception thrown\n");
}
#endif
reader.readEndElement("Property");
}
reader.readEndElement("Properties");
}
// Python Drawing feature ---------------------------------------------------------
namespace App {

View File

@@ -64,9 +64,6 @@ public:
virtual short mustExecute() const override;
void Restore(Base::XMLReader &reader) override;
protected:
/* virtual void onChanged(const App::Property* prop) override;*/
Base::BoundBox3d bbox;

View File

@@ -179,8 +179,13 @@ TopoDS_Shape DrawViewPart::getSourceShape(void) const
} else {
std::vector<TopoDS_Shape> sourceShapes;
for (auto& l:links) {
std::vector<TopoDS_Shape> shapeList = getShapesFromObject(l);
sourceShapes.insert(sourceShapes.end(),shapeList.begin(),shapeList.end());
auto shape = Part::Feature::getShape(l);
if(!shape.IsNull())
sourceShapes.push_back(shape);
else {
std::vector<TopoDS_Shape> shapeList = getShapesFromObject(l);
sourceShapes.insert(sourceShapes.end(),shapeList.begin(),shapeList.end());
}
}
BRep_Builder builder;
@@ -330,7 +335,7 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
geometryObject = buildGeometryObject(mirroredShape,viewAxis);
#if MOD_TECHDRAW_HANDLE_FACES
auto start = chrono::high_resolution_clock::now();
auto start = std::chrono::high_resolution_clock::now();
if (handleFaces() && !geometryObject->usePolygonHLR()) {
try {
extractFaces();
@@ -348,9 +353,9 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
//add centerlines to geometry edges list
addCenterLinesToGeom();
auto end = chrono::high_resolution_clock::now();
auto end = std::chrono::high_resolution_clock::now();
auto diff = end - start;
double diffOut = chrono::duration <double, milli> (diff).count();
double diffOut = std::chrono::duration <double, std::milli> (diff).count();
Base::Console().Log("TIMING - %s DVP spent: %.3f millisecs handling Faces\n",
getNameInDocument(),diffOut);
@@ -415,7 +420,7 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape,
viewAxis);
}
auto start = chrono::high_resolution_clock::now();
auto start = std::chrono::high_resolution_clock::now();
go->extractGeometry(TechDraw::ecHARD, //always show the hard&outline visible lines
true);
@@ -451,9 +456,9 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape,
go->extractGeometry(TechDraw::ecUVISO,
false);
}
auto end = chrono::high_resolution_clock::now();
auto end = std::chrono::high_resolution_clock::now();
auto diff = end - start;
double diffOut = chrono::duration <double, milli> (diff).count();
double diffOut = std::chrono::duration <double, std::milli> (diff).count();
Base::Console().Log("TIMING - %s DVP spent: %.3f millisecs in GO::extractGeometry\n",getNameInDocument(),diffOut);
const std::vector<TechDraw::BaseGeom *> & edges = go->getEdgeGeometry();