FreeCAD

Форк
0
/
Part2DObject.cpp 
276 строк · 10.3 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de>              *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
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.      *
10
 *                                                                         *
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.                  *
15
 *                                                                         *
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                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
# include <TopoDS_Shape.hxx>
26
# include <TopoDS_Face.hxx>
27
# include <TopoDS.hxx>
28
# include <gp_Pln.hxx>
29
# include <gp_Ax1.hxx>
30
# include <gp_Pnt.hxx>
31
# include <gp_Dir.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>
40
#endif
41

42
#ifndef M_PI
43
#define M_PI       3.14159265358979323846
44
#endif
45

46
#include <App/FeaturePythonPyImp.h>
47
#include <App/PropertyLinks.h>
48
#include <Base/Reader.h>
49

50
#include "Part2DObject.h"
51
#include "Part2DObjectPy.h"
52
#include "Geometry.h"
53

54

55
using namespace Part;
56

57
const int Part2DObject::H_Axis = -1;
58
const int Part2DObject::V_Axis = -2;
59
const int Part2DObject::N_Axis = -3;
60

61
PROPERTY_SOURCE_WITH_EXTENSIONS(Part::Part2DObject, Part::Feature)
62

63

64
Part2DObject::Part2DObject()
65
{
66
    AttachExtension::initExtension(this);
67
    this->setAttacher(new Attacher::AttachEnginePlane);
68
}
69

70

71
App::DocumentObjectExecReturn *Part2DObject::execute()
72
{
73
    return Feature::execute();
74
}
75

76
void Part2DObject::transformPlacement(const Base::Placement &transform)
77
{
78
    if (!AttachmentSupport.getValues().empty()) {
79
        //part->transformPlacement(transform);
80
        positionBySupport();
81
    } else {
82
        GeoFeature::transformPlacement(transform);
83
    }
84
}
85

86
int Part2DObject::getAxisCount() const
87
{
88
    return 0;
89
}
90

91
Base::Axis Part2DObject::getAxis(int axId) const
92
{
93
    if (axId == H_Axis) {
94
        return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0));
95
    }
96
    else if (axId == V_Axis) {
97
        return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0));
98
    }
99
    else if (axId == N_Axis) {
100
        return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,0,1));
101
    }
102
    return {};
103
}
104

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)
109
{
110
    if ( geometryIndex >= int(geomlist.size()))
111
        return false;
112

113
    gp_Pln plane(gp_Pnt(0,0,0),gp_Dir(0,0,1));
114

115
    Standard_Boolean periodic=Standard_False;
116
    double period = 0;
117
    Handle(Geom2d_Curve) primaryCurve;
118
    Handle(Geom_Geometry) geom = (geomlist[geometryIndex])->handle();
119
    Handle(Geom_Curve) curve3d = Handle(Geom_Curve)::DownCast(geom);
120

121
    if (curve3d.IsNull())
122
        return false;
123
    else {
124
        primaryCurve = GeomAPI::To2d(curve3d, plane);
125
        periodic = primaryCurve->IsPeriodic();
126
        if (periodic)
127
            period = primaryCurve->Period();
128
    }
129

130
    // create the intersector and projector functions
131
    Geom2dAPI_InterCurveCurve Intersector;
132
    Geom2dAPI_ProjectPointOnCurve Projector;
133

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

138
    // find intersection points
139
    geometryIndex1 = -1;
140
    geometryIndex2 = -1;
141
    double param1=-1e10,param2=1e10;
142
    gp_Pnt2d p1,p2;
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
152

153
                std::vector<gp_Pnt2d> points;
154

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>()) {
161

162
                    Part::GeomBoundedCurve * bcurve = static_cast<Part::GeomBoundedCurve *>(geomlist[id]);
163

164
                    points.emplace_back(bcurve->getStartPoint().x,bcurve->getStartPoint().y);
165
                    points.emplace_back(bcurve->getEndPoint().x,bcurve->getEndPoint().y);
166
                }
167

168
                Intersector.Init(primaryCurve, secondaryCurve, 1.0e-12);
169

170
                for (int i=1; i <= Intersector.NbPoints(); i++)
171
                    points.push_back(Intersector.Point(i));
172

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());
180
                        }
181
                        if (segm.HasLastPoint()) {
182
                            const IntRes2d_IntersectionPoint& fp = segm.LastPoint();
183
                            points.push_back(fp.Value());
184
                        }
185
                    }
186
                }
187

188
                for (auto p : points) {
189
                    // get the parameter of the intersection point on the primary curve
190
                    Projector.Init(p, primaryCurve);
191

192
                    if (Projector.NbPoints()<1 || Projector.LowerDistance() > Precision::Confusion())
193
                        continue;
194

195
                    double param = Projector.LowerDistanceParameter();
196

197
                    if (periodic) {
198
                        // transfer param into the interval (pickedParam-period pickedParam]
199
                        param = param - period * ceil((param-pickedParam) / period);
200
                        if (param > param1) {
201
                            param1 = param;
202
                            p1 = p;
203
                            geometryIndex1 = id;
204
                        }
205
                        param -= period; // transfer param into the interval (pickedParam pickedParam+period]
206
                        if (param < param2) {
207
                            param2 = param;
208
                            p2 = p;
209
                            geometryIndex2 = id;
210
                        }
211
                    }
212
                    else if (param < pickedParam && param > param1) {
213
                        param1 = param;
214
                        p1 = p;
215
                        geometryIndex1 = id;
216
                    }
217
                    else if (param > pickedParam && param < param2) {
218
                        param2 = param;
219
                        p2 = p;
220
                        geometryIndex2 = id;
221
                    }
222
                }
223
            }
224
        }
225
    }
226

227
    if (periodic) {
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)
231
                geometryIndex2 = -1;
232
            else
233
                geometryIndex1 = -1;
234
        }
235
    }
236

237
    if ( geometryIndex1 < 0 && geometryIndex2 < 0)
238
        return false;
239

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);
244
    return true;
245
}
246

247
void Part2DObject::acceptGeometry()
248
{
249
    // implemented in sub-classes
250
}
251

252
void Part2DObject::Restore(Base::XMLReader &reader)
253
{
254
    Part::Feature::Restore(reader);
255
}
256

257
// Python Drawing feature ---------------------------------------------------------
258

259
namespace App {
260
/// @cond DOXERR
261
  PROPERTY_SOURCE_TEMPLATE(Part::Part2DObjectPython, Part::Part2DObject)
262
  template<> const char* Part::Part2DObjectPython::getViewProviderName() const {
263
    return "PartGui::ViewProvider2DObjectPython";
264
  }
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);
269
        }
270
        return Py::new_reference_to(PythonObject);
271
  }
272
/// @endcond
273

274
// explicit template instantiation
275
  template class PartExport FeaturePythonT<Part::Part2DObject>;
276
}
277

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.