1
/***************************************************************************
2
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
25
# include <TopoDS_Shape.hxx>
26
# include <TopoDS_Face.hxx>
32
# include <GeomAPI_ProjectPointOnSurf.hxx>
33
# include <Geom_Plane.hxx>
34
# include <Geom2d_Curve.hxx>
35
# include <Geom2dAPI_InterCurveCurve.hxx>
36
# include <Geom2dAPI_ProjectPointOnCurve.hxx>
37
# include <GeomAPI.hxx>
38
# include <BRepAdaptor_Surface.hxx>
39
# include <IntRes2d_IntersectionSegment.hxx>
43
#define M_PI 3.14159265358979323846
46
#include <App/FeaturePythonPyImp.h>
47
#include <App/PropertyLinks.h>
48
#include <Base/Reader.h>
50
#include "Part2DObject.h"
51
#include "Part2DObjectPy.h"
57
const int Part2DObject::H_Axis = -1;
58
const int Part2DObject::V_Axis = -2;
59
const int Part2DObject::N_Axis = -3;
61
PROPERTY_SOURCE_WITH_EXTENSIONS(Part::Part2DObject, Part::Feature)
64
Part2DObject::Part2DObject()
66
AttachExtension::initExtension(this);
67
this->setAttacher(new Attacher::AttachEnginePlane);
71
App::DocumentObjectExecReturn *Part2DObject::execute()
73
return Feature::execute();
76
void Part2DObject::transformPlacement(const Base::Placement &transform)
78
if (!AttachmentSupport.getValues().empty()) {
79
//part->transformPlacement(transform);
82
GeoFeature::transformPlacement(transform);
86
int Part2DObject::getAxisCount() const
91
Base::Axis Part2DObject::getAxis(int axId) const
94
return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0));
96
else if (axId == V_Axis) {
97
return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0));
99
else if (axId == N_Axis) {
100
return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,0,1));
105
bool Part2DObject::seekTrimPoints(const std::vector<Geometry *> &geomlist,
106
int geometryIndex, const Base::Vector3d &point,
107
int &geometryIndex1, Base::Vector3d &intersect1,
108
int &geometryIndex2, Base::Vector3d &intersect2)
110
if ( geometryIndex >= int(geomlist.size()))
113
gp_Pln plane(gp_Pnt(0,0,0),gp_Dir(0,0,1));
115
Standard_Boolean periodic=Standard_False;
117
Handle(Geom2d_Curve) primaryCurve;
118
Handle(Geom_Geometry) geom = (geomlist[geometryIndex])->handle();
119
Handle(Geom_Curve) curve3d = Handle(Geom_Curve)::DownCast(geom);
121
if (curve3d.IsNull())
124
primaryCurve = GeomAPI::To2d(curve3d, plane);
125
periodic = primaryCurve->IsPeriodic();
127
period = primaryCurve->Period();
130
// create the intersector and projector functions
131
Geom2dAPI_InterCurveCurve Intersector;
132
Geom2dAPI_ProjectPointOnCurve Projector;
134
// find the parameter of the picked point on the primary curve
135
Projector.Init(gp_Pnt2d(point.x, point.y), primaryCurve);
136
double pickedParam = Projector.LowerDistanceParameter();
138
// find intersection points
141
double param1=-1e10,param2=1e10;
143
Handle(Geom2d_Curve) secondaryCurve;
144
for (int id=0; id < int(geomlist.size()); id++) {
145
// #0000624: Trim tool doesn't work with construction lines
146
if (id != geometryIndex/* && !geomlist[id]->Construction*/) {
147
geom = (geomlist[id])->handle();
148
curve3d = Handle(Geom_Curve)::DownCast(geom);
149
if (!curve3d.IsNull()) {
150
secondaryCurve = GeomAPI::To2d(curve3d, plane);
151
// perform the curves intersection
153
std::vector<gp_Pnt2d> points;
155
// #2463 Check for endpoints of secondarycurve on primary curve
156
// If the OCCT Intersector should detect endpoint tangency when trimming, then
157
// this is just a work-around until that bug is fixed.
158
// https://www.freecad.org/tracker/view.php?id=2463
159
// https://tracker.dev.opencascade.org/view.php?id=30217
160
if (geomlist[id]->isDerivedFrom<Part::GeomBoundedCurve>()) {
162
Part::GeomBoundedCurve * bcurve = static_cast<Part::GeomBoundedCurve *>(geomlist[id]);
164
points.emplace_back(bcurve->getStartPoint().x,bcurve->getStartPoint().y);
165
points.emplace_back(bcurve->getEndPoint().x,bcurve->getEndPoint().y);
168
Intersector.Init(primaryCurve, secondaryCurve, 1.0e-12);
170
for (int i=1; i <= Intersector.NbPoints(); i++)
171
points.push_back(Intersector.Point(i));
173
if (Intersector.NbSegments() > 0) {
174
const Geom2dInt_GInter& gInter = Intersector.Intersector();
175
for (int i=1; i <= gInter.NbSegments(); i++) {
176
const IntRes2d_IntersectionSegment& segm = gInter.Segment(i);
177
if (segm.HasFirstPoint()) {
178
const IntRes2d_IntersectionPoint& fp = segm.FirstPoint();
179
points.push_back(fp.Value());
181
if (segm.HasLastPoint()) {
182
const IntRes2d_IntersectionPoint& fp = segm.LastPoint();
183
points.push_back(fp.Value());
188
for (auto p : points) {
189
// get the parameter of the intersection point on the primary curve
190
Projector.Init(p, primaryCurve);
192
if (Projector.NbPoints()<1 || Projector.LowerDistance() > Precision::Confusion())
195
double param = Projector.LowerDistanceParameter();
198
// transfer param into the interval (pickedParam-period pickedParam]
199
param = param - period * ceil((param-pickedParam) / period);
200
if (param > param1) {
205
param -= period; // transfer param into the interval (pickedParam pickedParam+period]
206
if (param < param2) {
212
else if (param < pickedParam && param > param1) {
217
else if (param > pickedParam && param < param2) {
228
// in case both points coincide, cancel the selection of one of both
229
if (fabs(param2-param1-period) < 1e-10) {
230
if (param2 - pickedParam >= pickedParam - param1)
237
if ( geometryIndex1 < 0 && geometryIndex2 < 0)
240
if ( geometryIndex1 >= 0)
241
intersect1 = Base::Vector3d(p1.X(),p1.Y(),0.f);
242
if ( geometryIndex2 >= 0)
243
intersect2 = Base::Vector3d(p2.X(),p2.Y(),0.f);
247
void Part2DObject::acceptGeometry()
249
// implemented in sub-classes
252
void Part2DObject::Restore(Base::XMLReader &reader)
254
Part::Feature::Restore(reader);
257
// Python Drawing feature ---------------------------------------------------------
261
PROPERTY_SOURCE_TEMPLATE(Part::Part2DObjectPython, Part::Part2DObject)
262
template<> const char* Part::Part2DObjectPython::getViewProviderName() const {
263
return "PartGui::ViewProvider2DObjectPython";
265
template<> PyObject* Part::Part2DObjectPython::getPyObject() {
266
if (PythonObject.is(Py::_None())) {
267
// ref counter is set to 1
268
PythonObject = Py::Object(new FeaturePythonPyT<Part::Part2DObjectPy>(this),true);
270
return Py::new_reference_to(PythonObject);
274
// explicit template instantiation
275
template class PartExport FeaturePythonT<Part::Part2DObject>;