Moved generic Datum class to Part module to avoid Sketcher dependency on PartDesign

This commit is contained in:
jrheinlaender
2013-05-03 20:27:25 +04:30
committed by Stefan Tröger
parent 6b21b6937f
commit 857ede8847
36 changed files with 6297 additions and 1314 deletions

View File

@@ -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();