Part2DObject.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2008     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
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         // toggle if plane has a left-handed coordinate system
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     // +X/-X
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     // +Y/-Y
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     // +Z/-Z
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     // set Rotation matrix
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     // set pos vector
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     // check the angle against the Z Axis
00162     //Standard_Real a = Normal.Angle(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1)));
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     // create the intersector and projector functions
00192     Geom2dAPI_InterCurveCurve Intersector;
00193     Geom2dAPI_ProjectPointOnCurve Projector;
00194 
00195     // find the parameter of the picked point on the primary curve
00196     Projector.Init(gp_Pnt2d(point.x, point.y), primaryCurve);
00197     double pickedParam = Projector.LowerDistanceParameter();
00198 
00199     // find intersection points
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                 // perform the curves intersection
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                     // get the parameter of the intersection point on the primary curve
00216                     Projector.Init(p, primaryCurve);
00217                     double param = Projector.LowerDistanceParameter();
00218                     if (periodic) {
00219                         // transfer param into the interval (pickedParam-period pickedParam]
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; // transfer param into the interval (pickedParam pickedParam+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         // in case both points coincide, cancel the selection of one of both
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 // Python Drawing feature ---------------------------------------------------------
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 // explicit template instantiation
00279   template class PartExport FeaturePythonT<Part::Part2DObject>;
00280 }
00281 

Generated on Wed Nov 23 19:00:25 2011 for FreeCAD by  doxygen 1.6.1