00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <TopoDS_Shape.hxx>
00027 # include <TopoDS_Face.hxx>
00028 # include <TopoDS.hxx>
00029 # include <gp_Pln.hxx>
00030 # include <gp_Ax1.hxx>
00031 # include <gp_Pnt.hxx>
00032 # include <gp_Dir.hxx>
00033 # include <GeomAPI_ProjectPointOnSurf.hxx>
00034 # include <Geom_Plane.hxx>
00035 # include <Geom2d_Curve.hxx>
00036 # include <Geom2dAPI_InterCurveCurve.hxx>
00037 # include <Geom2dAPI_ProjectPointOnCurve.hxx>
00038 # include <GeomAPI.hxx>
00039 # include <BRepAdaptor_Surface.hxx>
00040 #endif
00041
00042 #ifndef M_PI
00043 #define M_PI 3.14159265358979323846
00044 #endif
00045
00046
00047
00048 #include "Part2DObject.h"
00049 #include "Geometry.h"
00050
00051
00052 using namespace Part;
00053
00054
00055 PROPERTY_SOURCE(Part::Part2DObject, Part::Feature)
00056
00057
00058 Part2DObject::Part2DObject()
00059 {
00060 ADD_PROPERTY_TYPE(Support,(0), "2D",(App::PropertyType)(App::Prop_None),"Support of the 2D geometry");
00061 }
00062
00063
00064 App::DocumentObjectExecReturn *Part2DObject::execute(void)
00065 {
00066
00067 return App::DocumentObject::StdReturn;
00068 }
00069
00070 Base::Placement Part2DObject::positionBySupport(const TopoDS_Face &face, const Base::Placement &Place)
00071 {
00072 if (face.IsNull())
00073 throw Base::Exception("Null Face in Part2DObject::positionBySupport()!");
00074
00075 bool Reverse = false;
00076 if (face.Orientation() == TopAbs_REVERSED)
00077 Reverse = true;
00078
00079 BRepAdaptor_Surface adapt(face);
00080
00081 if (adapt.GetType() != GeomAbs_Plane)
00082 throw Base::Exception("No planar Face in Part2DObject::positionBySupport()!");
00083
00084 gp_Pnt ObjOrg(Place.getPosition().x,Place.getPosition().y,Place.getPosition().z);
00085 gp_Pln plane = adapt.Plane();
00086 Standard_Boolean ok = plane.Direct();
00087 if (!ok) {
00088
00089 plane.UReverse();
00090 Reverse = !Reverse;
00091 }
00092
00093 gp_Ax1 Normal = plane.Axis();
00094 if (Reverse)
00095 Normal.Reverse();
00096
00097 Handle (Geom_Plane) gPlane = new Geom_Plane(plane);
00098 GeomAPI_ProjectPointOnSurf projector(ObjOrg,gPlane);
00099 gp_Pnt SketchBasePoint = projector.NearestPoint();
00100
00101 gp_Dir dir = Normal.Direction();
00102 gp_Ax3 SketchPos;
00103
00104 double cosNX = dir.Dot(gp::DX());
00105 double cosNY = dir.Dot(gp::DY());
00106 double cosNZ = dir.Dot(gp::DZ());
00107 std::vector<double> cosXYZ;
00108 cosXYZ.push_back(fabs(cosNX));
00109 cosXYZ.push_back(fabs(cosNY));
00110 cosXYZ.push_back(fabs(cosNZ));
00111
00112 int pos = std::max_element(cosXYZ.begin(), cosXYZ.end()) - cosXYZ.begin();
00113
00114
00115 if (pos == 0) {
00116 if (cosNX > 0)
00117 SketchPos = gp_Ax3(SketchBasePoint, dir, gp_Dir(0,1,0));
00118 else
00119 SketchPos = gp_Ax3(SketchBasePoint, dir, gp_Dir(0,-1,0));
00120 }
00121
00122 else if (pos == 1) {
00123 if (cosNY > 0)
00124 SketchPos = gp_Ax3(SketchBasePoint, dir, gp_Dir(-1,0,0));
00125 else
00126 SketchPos = gp_Ax3(SketchBasePoint, dir, gp_Dir(1,0,0));
00127 }
00128
00129 else {
00130 SketchPos = gp_Ax3(SketchBasePoint, dir, gp_Dir(1,0,0));
00131 }
00132
00133 gp_Trsf Trf;
00134 Trf.SetTransformation(SketchPos);
00135 Trf.Invert();
00136
00137 Base::Matrix4D mtrx;
00138
00139 gp_Mat m = Trf._CSFDB_Getgp_Trsfmatrix();
00140 gp_XYZ p = Trf._CSFDB_Getgp_Trsfloc();
00141 Standard_Real scale = 1.0;
00142
00143
00144 mtrx[0][0] = scale * m._CSFDB_Getgp_Matmatrix(0,0);
00145 mtrx[0][1] = scale * m._CSFDB_Getgp_Matmatrix(0,1);
00146 mtrx[0][2] = scale * m._CSFDB_Getgp_Matmatrix(0,2);
00147
00148 mtrx[1][0] = scale * m._CSFDB_Getgp_Matmatrix(1,0);
00149 mtrx[1][1] = scale * m._CSFDB_Getgp_Matmatrix(1,1);
00150 mtrx[1][2] = scale * m._CSFDB_Getgp_Matmatrix(1,2);
00151
00152 mtrx[2][0] = scale * m._CSFDB_Getgp_Matmatrix(2,0);
00153 mtrx[2][1] = scale * m._CSFDB_Getgp_Matmatrix(2,1);
00154 mtrx[2][2] = scale * m._CSFDB_Getgp_Matmatrix(2,2);
00155
00156
00157 mtrx[0][3] = p._CSFDB_Getgp_XYZx();
00158 mtrx[1][3] = p._CSFDB_Getgp_XYZy();
00159 mtrx[2][3] = p._CSFDB_Getgp_XYZz();
00160
00161
00162
00163
00164 return Base::Placement(mtrx);
00165 }
00166
00167 bool Part2DObject::seekTrimPoints(const std::vector<Geometry *> &geomlist,
00168 int GeoId, const Base::Vector3d &point,
00169 int &GeoId1, Base::Vector3d &intersect1,
00170 int &GeoId2, Base::Vector3d &intersect2)
00171 {
00172 if (GeoId >= int(geomlist.size()))
00173 return false;
00174
00175 gp_Pln plane(gp_Pnt(0,0,0),gp_Dir(0,0,1));
00176
00177 Standard_Boolean periodic=Standard_False;
00178 double period;
00179 Handle_Geom2d_Curve primaryCurve;
00180 Handle_Geom_Geometry geom = (geomlist[GeoId])->handle();
00181 Handle_Geom_Curve curve3d = Handle_Geom_Curve::DownCast(geom);
00182 if (curve3d.IsNull())
00183 return false;
00184 else {
00185 primaryCurve = GeomAPI::To2d(curve3d, plane);
00186 periodic = primaryCurve->IsPeriodic();
00187 if (periodic)
00188 period = primaryCurve->Period();
00189 }
00190
00191
00192 Geom2dAPI_InterCurveCurve Intersector;
00193 Geom2dAPI_ProjectPointOnCurve Projector;
00194
00195
00196 Projector.Init(gp_Pnt2d(point.x, point.y), primaryCurve);
00197 double pickedParam = Projector.LowerDistanceParameter();
00198
00199
00200 GeoId1 = -1;
00201 GeoId2 = -1;
00202 double param1=-1e10,param2=1e10;
00203 gp_Pnt2d p1,p2;
00204 Handle_Geom2d_Curve secondaryCurve;
00205 for (int id=0; id < int(geomlist.size()); id++) {
00206 if (id != GeoId && !geomlist[id]->Construction) {
00207 geom = (geomlist[id])->handle();
00208 curve3d = Handle_Geom_Curve::DownCast(geom);
00209 if (!curve3d.IsNull()) {
00210 secondaryCurve = GeomAPI::To2d(curve3d, plane);
00211
00212 Intersector.Init(primaryCurve, secondaryCurve, 1.0e-12);
00213 for (int i=1; i <= Intersector.NbPoints(); i++) {
00214 gp_Pnt2d p = Intersector.Point(i);
00215
00216 Projector.Init(p, primaryCurve);
00217 double param = Projector.LowerDistanceParameter();
00218 if (periodic) {
00219
00220 param = param - period * ceil((param-pickedParam) / period);
00221 if (param > param1) {
00222 param1 = param;
00223 p1 = p;
00224 GeoId1 = id;
00225 }
00226 param -= period;
00227 if (param < param2) {
00228 param2 = param;
00229 p2 = p;
00230 GeoId2 = id;
00231 }
00232 }
00233 else if (param < pickedParam && param > param1) {
00234 param1 = param;
00235 p1 = p;
00236 GeoId1 = id;
00237 }
00238 else if (param > pickedParam && param < param2) {
00239 param2 = param;
00240 p2 = p;
00241 GeoId2 = id;
00242 }
00243 }
00244 }
00245 }
00246 }
00247
00248 if (periodic) {
00249
00250 if (abs(param2-param1-period) < 1e-10) {
00251 if (param2 - pickedParam >= pickedParam - param1)
00252 GeoId2 = -1;
00253 else
00254 GeoId1 = -1;
00255 }
00256 }
00257
00258 if (GeoId1 < 0 && GeoId2 < 0)
00259 return false;
00260
00261 if (GeoId1 >= 0)
00262 intersect1 = Base::Vector3d(p1.X(),p1.Y(),0.f);
00263 if (GeoId2 >= 0)
00264 intersect2 = Base::Vector3d(p2.X(),p2.Y(),0.f);
00265 return true;
00266 }
00267
00268
00269
00270 namespace App {
00272 PROPERTY_SOURCE_TEMPLATE(Part::Part2DObjectPython, Part::Part2DObject)
00273 template<> const char* Part::Part2DObjectPython::getViewProviderName(void) const {
00274 return "PartGui::ViewProvider2DObjectPython";
00275 }
00277
00278
00279 template class PartExport FeaturePythonT<Part::Part2DObject>;
00280 }
00281