Moved generic Datum class to Part module to avoid Sketcher dependency on PartDesign
This commit is contained in:
committed by
Stefan Tröger
parent
6b21b6937f
commit
857ede8847
@@ -25,6 +25,7 @@
|
||||
#ifndef _PreComp_
|
||||
# include <TopoDS_Shape.hxx>
|
||||
# include <TopoDS_Face.hxx>
|
||||
# include <TopoDS_Edge.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
# include <TopExp_Explorer.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
@@ -34,6 +35,7 @@
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <BRepAdaptor_Curve.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <Geom_Line.hxx>
|
||||
# include <Geom_Plane.hxx>
|
||||
# include <Geom_Circle.hxx>
|
||||
# include <Geom_Ellipse.hxx>
|
||||
@@ -41,6 +43,9 @@
|
||||
# include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
# include <BRepOffsetAPI_NormalProjection.hxx>
|
||||
# include <BRepBuilderAPI_MakeFace.hxx>
|
||||
# include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
# include <GeomAPI_IntSS.hxx>
|
||||
# include <BRepProj_Projection.hxx>
|
||||
# include <Standard_Version.hxx>
|
||||
# include <cmath>
|
||||
# include <vector>
|
||||
@@ -56,8 +61,10 @@
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
#include <App/Plane.h>
|
||||
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/PartDesign/App/DatumFeature.h>
|
||||
#include <Mod/Part/App/DatumFeature.h>
|
||||
|
||||
#include "SketchObject.h"
|
||||
#include "SketchObjectPy.h"
|
||||
@@ -119,15 +126,7 @@ App::DocumentObjectExecReturn *SketchObject::execute(void)
|
||||
if (support == NULL)
|
||||
throw Base::Exception("Sketch support has been deleted");
|
||||
|
||||
if (support->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) {
|
||||
// We don't want to handle this case in Part::Part2DObject because then Part would depend on PartDesign
|
||||
PartDesign::Plane* plane = static_cast<PartDesign::Plane*>(support);
|
||||
Base::Vector3d pos = plane->_Base.getValue();
|
||||
Base::Vector3d normal = plane->_Normal.getValue();
|
||||
this->Placement.setValue(Base::Placement(pos, Base::Rotation(Base::Vector3d(0,0,1), normal)));
|
||||
} else {
|
||||
this->positionBySupport();
|
||||
}
|
||||
this->positionBySupport();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
@@ -2713,8 +2712,10 @@ int SketchObject::DeleteUnusedInternalGeometry(int GeoId)
|
||||
|
||||
int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName)
|
||||
{
|
||||
// so far only externals to the support of the sketch
|
||||
// so far only externals to the support of the sketch and datum features
|
||||
if (Support.getValue() != Obj)
|
||||
if (!Obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) &&
|
||||
!Obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId()))
|
||||
return -1;
|
||||
|
||||
// get the actual lists of the externals
|
||||
@@ -2889,6 +2890,56 @@ const Part::Geometry* SketchObject::getGeometry(int GeoId) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Auxiliary method
|
||||
Part::Geometry* projectLine(const BRepAdaptor_Curve& curve, const Handle(Geom_Plane)& gPlane, const Base::Placement& invPlm)
|
||||
{
|
||||
double first = curve.FirstParameter();
|
||||
bool infinite = false;
|
||||
if (fabs(first) > 1E99) {
|
||||
// TODO: What is OCE's definition of Infinite?
|
||||
// TODO: The clean way to do this is to handle a new sketch geometry Geom::Line
|
||||
// but its a lot of work to implement...
|
||||
first = -10000;
|
||||
//infinite = true;
|
||||
}
|
||||
double last = curve.LastParameter();
|
||||
if (fabs(last) > 1E99) {
|
||||
last = +10000;
|
||||
//infinite = true;
|
||||
}
|
||||
|
||||
gp_Pnt P1 = curve.Value(first);
|
||||
gp_Pnt P2 = curve.Value(last);
|
||||
|
||||
GeomAPI_ProjectPointOnSurf proj1(P1,gPlane);
|
||||
P1 = proj1.NearestPoint();
|
||||
GeomAPI_ProjectPointOnSurf proj2(P2,gPlane);
|
||||
P2 = proj2.NearestPoint();
|
||||
|
||||
Base::Vector3d p1(P1.X(),P1.Y(),P1.Z());
|
||||
Base::Vector3d p2(P2.X(),P2.Y(),P2.Z());
|
||||
invPlm.multVec(p1,p1);
|
||||
invPlm.multVec(p2,p2);
|
||||
|
||||
if (Base::Distance(p1,p2) < Precision::Confusion()) {
|
||||
Base::Vector3d p = (p1 + p2) / 2;
|
||||
Part::GeomPoint* point = new Part::GeomPoint(p);
|
||||
point->Construction = true;
|
||||
return point;
|
||||
}
|
||||
else if (!infinite) {
|
||||
Part::GeomLineSegment* line = new Part::GeomLineSegment();
|
||||
line->setPoints(p1,p2);
|
||||
line->Construction = true;
|
||||
return line;
|
||||
} else {
|
||||
Part::GeomLine* line = new Part::GeomLine();
|
||||
line->setLine(p1, p2 - p1);
|
||||
line->Construction = true;
|
||||
return line;
|
||||
}
|
||||
}
|
||||
|
||||
bool SketchObject::evaluateSupport(void)
|
||||
{
|
||||
// returns false if the shape if broken, null or non-planar
|
||||
@@ -3028,18 +3079,39 @@ void SketchObject::rebuildExternalGeometry(void)
|
||||
ExternalGeo.push_back(VLine);
|
||||
for (int i=0; i < int(Objects.size()); i++) {
|
||||
const App::DocumentObject *Obj=Objects[i];
|
||||
const std::string SubElement=SubElements[i];
|
||||
|
||||
const Part::Feature *refObj=static_cast<const Part::Feature*>(Obj);
|
||||
const Part::TopoShape& refShape=refObj->Shape.getShape();
|
||||
const std::string SubElement=SubElements[i];
|
||||
|
||||
TopoDS_Shape refSubShape;
|
||||
try {
|
||||
refSubShape = refShape.getSubShape(SubElement.c_str());
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
|
||||
if (Obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
|
||||
const Part::Datum* datum = static_cast<const Part::Datum*>(Obj);
|
||||
refSubShape = datum->Shape.getValue();
|
||||
} else if (Obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
try {
|
||||
const Part::Feature *refObj=static_cast<const Part::Feature*>(Obj);
|
||||
const Part::TopoShape& refShape=refObj->Shape.getShape();
|
||||
refSubShape = refShape.getSubShape(SubElement.c_str());
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
} else if (Obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
|
||||
const App::Plane* pl = static_cast<const App::Plane*>(Obj);
|
||||
Base::Placement plm = pl->Placement.getValue();
|
||||
Base::Vector3d base = plm.getPosition();
|
||||
Base::Rotation rot = plm.getRotation();
|
||||
Base::Vector3d normal(0,0,1);
|
||||
rot.multVec(normal, normal);
|
||||
gp_Pln plane(gp_Pnt(base.x,base.y,base.z), gp_Dir(normal.x, normal.y, normal.z));
|
||||
BRepBuilderAPI_MakeFace fBuilder(plane);
|
||||
if (!fBuilder.IsDone())
|
||||
throw Base::Exception("Sketcher: addExternal(): Failed to build face from App::Plane");
|
||||
|
||||
TopoDS_Face f = TopoDS::Face(fBuilder.Shape());
|
||||
refSubShape = f;
|
||||
} else {
|
||||
throw Base::Exception("Datum feature type is not yet supported as external geometry for a sketch");
|
||||
}
|
||||
|
||||
switch (refSubShape.ShapeType())
|
||||
@@ -3049,8 +3121,27 @@ void SketchObject::rebuildExternalGeometry(void)
|
||||
const TopoDS_Face& face = TopoDS::Face(refSubShape);
|
||||
BRepAdaptor_Surface surface(face);
|
||||
if (surface.GetType() == GeomAbs_Plane) {
|
||||
// Check that the plane is perpendicular to the sketch plane
|
||||
Geom_Plane plane = surface.Plane();
|
||||
gp_Dir dnormal = plane.Axis().Direction();
|
||||
gp_Dir snormal = sketchPlane.Axis().Direction();
|
||||
if (fabs(dnormal.Angle(snormal) - M_PI_2) < Precision::Confusion()) {
|
||||
// Get vector that is normal to both sketch plane normal and plane normal. This is the line's direction
|
||||
gp_Dir lnormal = dnormal.Crossed(snormal);
|
||||
BRepBuilderAPI_MakeEdge builder(gp_Lin(plane.Location(), lnormal));
|
||||
builder.Build();
|
||||
if (builder.IsDone()) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(builder.Shape());
|
||||
BRepAdaptor_Curve curve(edge);
|
||||
if (curve.GetType() == GeomAbs_Line) {
|
||||
ExternalGeo.push_back(projectLine(curve, gPlane, invPlm));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
throw Base::Exception("Non-planar faces are not yet supported for external geometry of sketches");
|
||||
}
|
||||
throw Base::Exception("Faces are not yet supported for external geometry of sketches");
|
||||
}
|
||||
break;
|
||||
case TopAbs_EDGE:
|
||||
@@ -3058,31 +3149,7 @@ void SketchObject::rebuildExternalGeometry(void)
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(refSubShape);
|
||||
BRepAdaptor_Curve curve(edge);
|
||||
if (curve.GetType() == GeomAbs_Line) {
|
||||
gp_Pnt P1 = curve.Value(curve.FirstParameter());
|
||||
gp_Pnt P2 = curve.Value(curve.LastParameter());
|
||||
|
||||
GeomAPI_ProjectPointOnSurf proj1(P1,gPlane);
|
||||
P1 = proj1.NearestPoint();
|
||||
GeomAPI_ProjectPointOnSurf proj2(P2,gPlane);
|
||||
P2 = proj2.NearestPoint();
|
||||
|
||||
Base::Vector3d p1(P1.X(),P1.Y(),P1.Z());
|
||||
Base::Vector3d p2(P2.X(),P2.Y(),P2.Z());
|
||||
invPlm.multVec(p1,p1);
|
||||
invPlm.multVec(p2,p2);
|
||||
|
||||
if (Base::Distance(p1,p2) < Precision::Confusion()) {
|
||||
Base::Vector3d p = (p1 + p2) / 2;
|
||||
Part::GeomPoint* point = new Part::GeomPoint(p);
|
||||
point->Construction = true;
|
||||
ExternalGeo.push_back(point);
|
||||
}
|
||||
else {
|
||||
Part::GeomLineSegment* line = new Part::GeomLineSegment();
|
||||
line->setPoints(p1,p2);
|
||||
line->Construction = true;
|
||||
ExternalGeo.push_back(line);
|
||||
}
|
||||
ExternalGeo.push_back(projectLine(curve, gPlane, invPlm));
|
||||
}
|
||||
else if (curve.GetType() == GeomAbs_Circle) {
|
||||
gp_Dir vec1 = sketchPlane.Axis().Direction();
|
||||
|
||||
Reference in New Issue
Block a user