Base::Vector3d Extrusion::calculateShapeNormal(const App::PropertyLink& shapeLink) { if (!shapeLink.getValue()) throw Base::Exception("calculateShapeNormal: link is empty"); const App::DocumentObject* docobj = shapeLink.getValue(); //special case for sketches and the like: no matter what shape they have, use their local Z axis. if (docobj->isDerivedFrom(Part::Part2DObject::getClassTypeId())){ const Part::Part2DObject* p2do = static_cast<const Part::Part2DObject*>(docobj); Base::Vector3d OZ (0.0, 0.0, 1.0); Base::Vector3d result; p2do->Placement.getValue().getRotation().multVec(OZ, result); return result; } //extract the shape if (! docobj->isDerivedFrom(Part::Feature::getClassTypeId())) throw Base::TypeError("Linked object doesn't have shape."); const TopoShape &tsh = static_cast<const Part::Feature*>(docobj)->Shape.getShape(); TopoDS_Shape sh = tsh.getShape(); if (sh.IsNull()) throw Base::Exception("calculateShapeNormal: link points to a valid object, but its shape is null."); //find plane BRepLib_FindSurface planeFinder(sh, -1, /*OnlyPlane=*/true); if (! planeFinder.Found()) throw Base::ValueError("Can't find normal direction, because the shape is not on a plane."); //find plane normal and return result. GeomAdaptor_Surface surf(planeFinder.Surface()); gp_Dir normal = surf.Plane().Axis().Direction(); //now se know the plane. But if there are faces, the //plane normal direction is not dependent on face orientation (because findPlane only uses edges). //let's fix that. TopExp_Explorer ex(sh, TopAbs_FACE); if(ex.More()) { BRepAdaptor_Surface surf(TopoDS::Face(ex.Current())); normal = surf.Plane().Axis().Direction(); if (ex.Current().Orientation() == TopAbs_REVERSED){ normal.Reverse(); } } return Base::Vector3d(normal.X(), normal.Y(), normal.Z()); }
//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"); }