[TD]fix sketch location in view

This commit is contained in:
wandererfan
2023-10-02 11:01:02 -04:00
committed by WandererFan
parent 255e9eb434
commit ed72c03df3
5 changed files with 65 additions and 61 deletions

View File

@@ -168,7 +168,7 @@ DrawViewPart::~DrawViewPart()
//! XSource property lists
TopoDS_Shape DrawViewPart::getSourceShape(bool fuse) const
{
// Base::Console().Message("DVP::getSourceShape()\n");
// Base::Console().Message("DVP::getSourceShape()\n");
const std::vector<App::DocumentObject*>& links = getAllSources();
if (links.empty()) {
return TopoDS_Shape();
@@ -203,11 +203,15 @@ std::vector<App::DocumentObject*> DrawViewPart::getAllSources() const
//! pick supported 2d shapes out of the Source properties and
//! add them directly to the geometry without going through HLR
//! NOTE: this is for loose 2d shapes such as Part line or circle and is
//! not meant to include complex 2d shapes such as Sketches.
void DrawViewPart::addShapes2d(void)
{
// Base::Console().Message("DVP::addShapes2d()\n");
// get all the 2d shapes in the sources, then pick through them for loose edges
// or vertices.
std::vector<TopoDS_Shape> shapes = ShapeExtractor::getShapes2d(getAllSources());
for (auto& s : shapes) {
//just vertices for now
if (s.ShapeType() == TopAbs_VERTEX) {
gp_Pnt gp = BRep_Tool::Pnt(TopoDS::Vertex(s));
Base::Vector3d vp(gp.X(), gp.Y(), gp.Z());
@@ -218,8 +222,7 @@ void DrawViewPart::addShapes2d(void)
geometryObject->addVertex(v1);
}
else if (s.ShapeType() == TopAbs_EDGE) {
//not supporting edges yet. Why?
//Base::Console().Message("DVP::add2dShapes - found loose edge - isNull: %d\n", s.IsNull());
Base::Console().Message("DVP::add2dShapes - found loose edge - isNull: %d\n", s.IsNull());
TopoDS_Shape sTrans = ShapeUtils::moveShape(s,
m_saveCentroid * -1.0);
TopoDS_Shape sScale = ShapeUtils::scaleShape(sTrans,
@@ -229,7 +232,10 @@ void DrawViewPart::addShapes2d(void)
BaseGeomPtr bg = projectEdge(edge);
geometryObject->addEdge(bg);
//save connection between source feat and this edge
} else {
// message for developers.
//Base::Console().Message("DEVEL: DVP::addShapes2d - shape is not a vertex or edge\n");
}
}
}

View File

@@ -41,15 +41,18 @@
#include <Base/Placement.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/PrimitiveFeature.h>
#include <Mod/Part/App/FeaturePartCircle.h>
//#include <Mod/Sketcher/App/SketchObject.h>
#include "ShapeExtractor.h"
#include "DrawUtil.h"
#include "Preferences.h"
#include "ShapeUtils.h"
using namespace TechDraw;
using DU = DrawUtil;
using SU = ShapeUtils;
std::vector<TopoDS_Shape> ShapeExtractor::getShapes2d(const std::vector<App::DocumentObject*> links, bool overridePref)
{
@@ -66,30 +69,23 @@ std::vector<TopoDS_Shape> ShapeExtractor::getShapes2d(const std::vector<App::Doc
for (auto& d: objs) {
if (is2dObject(d)) {
if (d->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
//need to apply global placement here. ??? because 2d shapes (Points so far)
//don't get gp from Part::feature::getShape() ????
const Part::Feature* pf = static_cast<const Part::Feature*>(d);
Part::TopoShape ts = pf->Shape.getShape();
ts.setPlacement(pf->globalPlacement());
shapes2d.push_back(ts.getShape());
shapes2d.push_back(getLocatedShape(d));
}
}
}
} else {
if (is2dObject(l)) {
if (l->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
//need to apply placement here
const Part::Feature* pf = static_cast<const Part::Feature*>(l);
Part::TopoShape ts = pf->Shape.getShape();
ts.setPlacement(pf->globalPlacement());
shapes2d.push_back(ts.getShape());
}
shapes2d.push_back(getLocatedShape(l));
} // other 2d objects would go here - Draft objects?
}
}
}
return shapes2d;
}
//! get the located and oriented shapes corresponding to the the links. If the shapes are to be
//! fused, include2d should be false as 2d & 3d shapes may not fuse.
TopoDS_Shape ShapeExtractor::getShapes(const std::vector<App::DocumentObject*> links, bool include2d)
{
// Base::Console().Message("SE::getShapes() - links in: %d\n", links.size());
@@ -108,8 +104,8 @@ TopoDS_Shape ShapeExtractor::getShapes(const std::vector<App::DocumentObject*> l
}
} else {
auto shape = Part::Feature::getShape(l);
if(!shape.IsNull()) {
sourceShapes.push_back(shape);
if(!SU::isShapeReallyNull((shape))) {
sourceShapes.push_back(getLocatedShape(l));
} else {
std::vector<TopoDS_Shape> shapeList = getShapesFromObject(l);
sourceShapes.insert(sourceShapes.end(), shapeList.begin(), shapeList.end());
@@ -120,33 +116,29 @@ TopoDS_Shape ShapeExtractor::getShapes(const std::vector<App::DocumentObject*> l
BRep_Builder builder;
TopoDS_Compound comp;
builder.MakeCompound(comp);
bool found = false;
for (auto& s:sourceShapes) {
if (s.IsNull()) {
if (SU::isShapeReallyNull(s)) {
continue;
} else if (s.ShapeType() < TopAbs_SOLID) {
//clean up composite shapes
TopoDS_Shape cleanShape = stripInfiniteShapes(s);
if (!cleanShape.IsNull()) {
builder.Add(comp, cleanShape);
found = true;
}
} else if (Part::TopoShape(s).isInfinite()) {
continue; //simple shape is infinite
} else {
//a simple shape - add to compound
builder.Add(comp, s);
found = true;
}
}
//it appears that an empty compound is !IsNull(), so we need to check a different way
//if we added anything to the compound.
if (found) {
if (!SU::isShapeReallyNull(comp)) {
// BRepTools::Write(comp, "SEResult.brep"); //debug
return comp;
}
Base::Console().Error("ShapeExtractor failed to get shape.\n");
// Base::Console().Error("DEVEL: ShapeExtractor failed to get any shape.\n");
return TopoDS_Shape();
}
@@ -263,25 +255,7 @@ std::vector<TopoDS_Shape> ShapeExtractor::getShapesFromObject(const App::Documen
App::Property* gProp = docObj->getPropertyByName("Group");
App::Property* sProp = docObj->getPropertyByName("Shape");
if (docObj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
const Part::Feature* pf = static_cast<const Part::Feature*>(docObj);
Part::TopoShape ts(pf->Shape.getShape());
//ts might be garbage, better check
try {
if (!ts.isNull()) {
ts.setPlacement(pf->globalPlacement());
result.push_back(ts.getShape());
}
}
catch (Standard_Failure& e) {
Base::Console().Error("ShapeExtractor - %s encountered OCC error: %s \n", docObj->getNameInDocument(), e.GetMessageString());
return result;
}
catch (...) {
Base::Console().Error("ShapeExtractor failed to retrieve shape from %s\n", docObj->getNameInDocument());
return result;
}
result.push_back(getLocatedShape(docObj));
} else if (gex) { //is a group extension
std::vector<App::DocumentObject*> objs = gex->Group.getValues();
std::vector<TopoDS_Shape> shapes;
@@ -307,8 +281,7 @@ std::vector<TopoDS_Shape> ShapeExtractor::getShapesFromObject(const App::Documen
} else if (sProp) { //has a Shape property
Part::PropertyPartShape* shape = dynamic_cast<Part::PropertyPartShape*>(sProp);
if (shape) {
TopoDS_Shape occShape = shape->getValue();
result.push_back(occShape);
result.push_back(getLocatedShape(docObj));
}
}
return result;
@@ -392,21 +365,20 @@ bool ShapeExtractor::is2dObject(App::DocumentObject* obj)
return false;
}
//skip edges for now.
// just these for now
bool ShapeExtractor::isEdgeType(App::DocumentObject* obj)
{
(void) obj;
bool result = false;
// Base::Type t = obj->getTypeId();
// if (t.isDerivedFrom(Part::Line::getClassTypeId()) ) {
// result = true;
// } else if (t.isDerivedFrom(Part::Circle::getClassTypeId())) {
// result = true;
// } else if (t.isDerivedFrom(Part::Ellipse::getClassTypeId())) {
// result = true;
// } else if (t.isDerivedFrom(Part::RegularPolygon::getClassTypeId())) {
// result = true;
// }
Base::Type t = obj->getTypeId();
if (t.isDerivedFrom(Part::Line::getClassTypeId()) ) {
result = true;
} else if (t.isDerivedFrom(Part::Circle::getClassTypeId())) {
result = true;
} else if (t.isDerivedFrom(Part::Ellipse::getClassTypeId())) {
result = true;
} else if (t.isDerivedFrom(Part::RegularPolygon::getClassTypeId())) {
result = true;
}
return result;
}
@@ -439,9 +411,11 @@ bool ShapeExtractor::isDraftPoint(App::DocumentObject* obj)
return false;
}
//! get the location of a point object
Base::Vector3d ShapeExtractor::getLocation3dFromFeat(App::DocumentObject* obj)
{
// Base::Console().Message("SE::getLocation3dFromFeat()\n");
Base::Console().Message("SE::getLocation3dFromFeat()\n");
if (!isPointType(obj)) {
return Base::Vector3d(0.0, 0.0, 0.0);
}
@@ -465,6 +439,18 @@ Base::Vector3d ShapeExtractor::getLocation3dFromFeat(App::DocumentObject* obj)
return Base::Vector3d(0.0, 0.0, 0.0);
}
//! get the located and oriented version of docObj shape
TopoDS_Shape ShapeExtractor::getLocatedShape(const App::DocumentObject* docObj)
{
Part::TopoShape shape = Part::Feature::getShape(docObj);
const Part::Feature* pf = dynamic_cast<const Part::Feature*>(docObj);
if (pf) {
shape.setPlacement(pf->globalPlacement());
}
return shape.getShape();
}
//! true if we should include loose 2d geometry
bool ShapeExtractor::prefAdd2d()
{
return Preferences::getPreferenceGroup("General")->GetBool("ShowLoose2d", false);

View File

@@ -50,11 +50,13 @@ public:
static bool isEdgeType(App::DocumentObject* obj);
static bool isPointType(App::DocumentObject* obj);
static bool isDraftPoint(App::DocumentObject* obj);
static Base::Vector3d getLocation3dFromFeat(App::DocumentObject* obj);
static Base::Vector3d getLocation3dFromFeat(App::DocumentObject *obj);
static bool prefAdd2d();
static TopoDS_Shape stripInfiniteShapes(TopoDS_Shape inShape);
static TopoDS_Shape getLocatedShape(const App::DocumentObject* docObj);
protected:
private:

View File

@@ -367,3 +367,12 @@ std::pair<Base::Vector3d, Base::Vector3d> ShapeUtils::getEdgeEnds(TopoDS_Edge ed
return result;
}
//! check for shape is null or shape has no subshapes(vertex/edge/face/etc)
//! this handles the case of an empty compound which is not IsNull, but has no
//! content.
bool ShapeUtils::isShapeReallyNull(TopoDS_Shape shape)
{
// if the shape is null or it has no subshapes, then it is really null
return shape.IsNull() || !TopoDS_Iterator(shape).More();
}

View File

@@ -108,6 +108,7 @@ public:
static std::pair<Base::Vector3d, Base::Vector3d> getEdgeEnds(TopoDS_Edge edge);
static bool isShapeReallyNull(TopoDS_Shape shape);
};
}