0023404: Create SquareConfusion function in Precision package for speed and convenience
[occt.git] / src / Draft / Draft_Modification_1.cxx
CommitLineData
b311480e 1// Created on: 1994-12-02
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1994-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <Draft_Modification.jxx>
23
24#include <BRep_Tool.hxx>
25#include <BRep_Builder.hxx>
26
27#include <BRepLib_MakeFace.hxx>
28
29#include <TopLoc_Location.hxx>
30#include <TopExp_Explorer.hxx>
31#include <TopTools_ListIteratorOfListOfShape.hxx>
32
33#include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
34#include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
35#include <Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx>
36#include <Draft_FaceInfo.hxx>
37#include <Draft_EdgeInfo.hxx>
38#include <Draft_VertexInfo.hxx>
39#include <BRep_Tool.hxx>
40#include <BRep_Tool.hxx>
41
42#include <Geom_Surface.hxx>
43#include <Geom_RectangularTrimmedSurface.hxx>
44
45
46#include <Geom2d_Line.hxx>
47#include <Geom_Plane.hxx>
48#include <Geom_SurfaceOfLinearExtrusion.hxx>
49#include <Geom_CylindricalSurface.hxx>
50#include <Geom_ConicalSurface.hxx>
51#include <Geom_Curve.hxx>
52#include <Geom_Line.hxx>
53#include <Geom_Circle.hxx>
54#include <Geom_Ellipse.hxx>
55#include <Geom_Parabola.hxx>
56#include <Geom_Hyperbola.hxx>
57#include <Geom_TrimmedCurve.hxx>
58#include <GeomAdaptor_Curve.hxx>
59#include <GeomAdaptor_Surface.hxx>
60#include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
61
62#include <gp_Vec.hxx>
63#include <gp_Lin.hxx>
64#include <gp_Pln.hxx>
65#include <gp_Circ.hxx>
66#include <gp_Elips.hxx>
67#include <gp_Parab.hxx>
68#include <gp_Hypr.hxx>
69
70#include <IntCurveSurface_HInter.hxx>
71#include <GeomInt_IntSS.hxx>
72#include <IntCurveSurface_IntersectionPoint.hxx>
73#include <IntAna_QuadQuadGeo.hxx>
74#include <IntAna_IntConicQuad.hxx>
75
76#include <Extrema_ExtPC.hxx>
77#include <BRepExtrema_ExtPC.hxx>
78#include <BRepExtrema_ExtCF.hxx>
79
80#include <Standard_DomainError.hxx>
81#include <Standard_Failure.hxx>
82#include <Standard_NotImplemented.hxx>
83
84#include <TopTools_MapOfShape.hxx>
85#include <TopTools_MapIteratorOfMapOfShape.hxx>
86
87#include <gp.hxx>
88#include <Precision.hxx>
89#include <ElCLib.hxx>
90#include <ElSLib.hxx>
91#include <BRepTools.hxx>
92#include <TopoDS.hxx>
93#include <TopExp.hxx>
94
95#include <GeomAdaptor_HCurve.hxx>
96#include <GeomAdaptor_HSurface.hxx>
97#include <GeomAPI_ProjectPointOnSurf.hxx>
98
99#include <GeomAPI_ProjectPointOnCurve.hxx>
100
101#include <Geom2d_TrimmedCurve.hxx>
102#include <Geom2dAPI_ProjectPointOnCurve.hxx>
103#include <Geom2d_BSplineCurve.hxx>
104#include <Geom2dConvert.hxx>
105#include <Geom2dAdaptor_HCurve.hxx>
106#include <Adaptor3d_CurveOnSurface.hxx>
107
108#include <GeomProjLib.hxx>
109#include <TColgp_Array1OfPnt2d.hxx>
110#include <Geom2d_BezierCurve.hxx>
111#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
112
113#include <Adaptor3d_HCurveOnSurface.hxx>
114#include <ProjLib_CompProjectedCurve.hxx>
115#include <ProjLib_HCompProjectedCurve.hxx>
116#include <Approx_CurveOnSurface.hxx>
117
118#include <GeomConvert_CompCurveToBSplineCurve.hxx>
119
120
121static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo&,
122 Draft_DataMapOfEdgeEdgeInfo&,
123 const TopoDS_Vertex&,
124 Draft_VertexInfo&,
125 GeomAdaptor_Curve&,
126 GeomAdaptor_Surface&);
127
128static Standard_Real Parameter(const Handle(Geom_Curve)&,
129 const gp_Pnt&,
130 Standard_Integer&);
131
132static Standard_Real SmartParameter(Draft_EdgeInfo&,
133 const Standard_Real EdgeTol,
134 const gp_Pnt&,
135 const Standard_Integer,
136 const Handle(Geom_Surface)&,
137 const Handle(Geom_Surface)&);
138
139static TopAbs_Orientation Orientation(const TopoDS_Shape&,
140 const TopoDS_Face&);
141
142static Standard_Boolean FindRotation(const gp_Pln&,
143 const TopAbs_Orientation,
144 const gp_Dir&,
145 const Standard_Real,
146 const gp_Pln&,
147 gp_Ax1&,
148 Standard_Real&);
149
150
151//=======================================================================
152//function : InternalAdd
153//purpose :
154//=======================================================================
155
156Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
157 const gp_Dir& Direction,
158 const Standard_Real Angle,
159 const gp_Pln& NeutralPlane,
160 const Standard_Boolean Flag)
161{
162
163 if (myFMap.IsBound(F)) {
164 return (badShape.IsNull());
165 }
166
167 TopAbs_Orientation oris = Orientation(myShape,F);
168 TopLoc_Location Lo;
169 //gp_Dir NewDirection = Direction;
170 //Standard_Real NewAngle = Angle;
171 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Lo);
172 S = Handle(Geom_Surface)::DownCast(S->Transformed(Lo.Transformation()));
173 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
174 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
175 }
176 Handle(Geom_Surface) NewS;
177 Handle(Geom_Circle) theCircle;
178
179 Standard_Boolean postponed = (Flag == Standard_False);
180 if (postponed) {
181 Handle(Standard_Type) typS = S->DynamicType();
182 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
183 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
184 gp_Circ Cir;
185 if (typS == STANDARD_TYPE(Geom_CylindricalSurface)) {
186 gp_Cylinder cyl =
187 Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
188 gp_Ax1 axcyl = cyl.Axis();
189 Cir = ElSLib::CylinderVIso( cyl.Position(), cyl.Radius(), 0.);
190 gp_Vec VV(cyl.Location(),NeutralPlane.Location());
191 Cir.Translate(VV.Dot(axcyl.Direction())*axcyl.Direction());
192 }
193 else {
194 Handle(Geom_Curve) Cbas =
195 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
196 gp_Dir theDirextr =
197 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
198
199 if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
200 Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
201 }
202 if (Cbas->IsKind(STANDARD_TYPE(Geom_Circle))) {
203 Cir = Handle(Geom_Circle)::DownCast(Cbas)->Circ();
204 gp_Dir dircir = Cir.Axis().Direction();
205 if (!Direction.IsParallel(dircir,Precision::Angular())) {
206 badShape = F;
207 errStat = Draft_FaceRecomputation;
208 return Standard_False;
209 }
210 }
211 else {
212 badShape = F;
213 errStat = Draft_FaceRecomputation;
214 return Standard_False;
215 }
216
217 gp_Ax3 Axis = NeutralPlane.Position();
218 Standard_Real L =
219 gp_Vec(Cir.Location(),Axis.Location()).
220 Dot(Axis.Direction());
221 Standard_Real Cos = theDirextr.Dot(Axis.Direction());
222 gp_Vec VV = ( L / Cos) * theDirextr;
223 Cir.Translate(VV);
224 }
225
226 theCircle = new Geom_Circle(Cir);
227
228 }
229 else {
230 postponed = Standard_False;
231 }
232 }
233
234
235 if (!postponed) {
236 NewS = NewSurface(S,oris,Direction,Angle,NeutralPlane);
237 if (NewS.IsNull()) {
238 badShape = F;
239 errStat = Draft_FaceRecomputation;
240 return Standard_False;
241 }
0d969553 242 // To avoid some problems with infinite restrictions
7fd59977 243 const Handle(Standard_Type)& typs = NewS->DynamicType();
244 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
245 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
246 Standard_Real umin,umax,vmin,vmax;
247 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
248 if (!Precision::IsNegativeInfinite(vmin) &&
249 !Precision::IsPositiveInfinite(vmax)) {
250 Standard_Real deltav = 10.*(vmax-vmin);
251 if(typs == STANDARD_TYPE(Geom_CylindricalSurface)) {
252 vmin = vmin - deltav;
253 vmax = vmax + deltav;
254 }
255 else {
256 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
257 Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
0d969553 258 if (vmin < Vapex) { // vmax should not exceed Vapex
7fd59977 259 if (vmax + deltav > Vapex) {
260 vmax = Vapex;
261 vmin = vmin - 10.*(vmax - vmin);
0d969553 262 // JAG debug to avoid apex
7fd59977 263 vmax = vmax-Precision::Confusion();
264 }
265 else {
266 vmin = vmin - deltav;
267 vmax = vmax + deltav;
268 }
269 }
0d969553 270 else { // Vapex <= vmin < vmax
7fd59977 271 if (vmin - deltav < Vapex) {
272 vmin = Vapex;
273 vmax = vmax + 10.*(vmax - vmin);
0d969553 274 // JAG debug to avoid apex
7fd59977 275 vmin = vmin+Precision::Confusion();
276 }
277 else {
278 vmin = vmin - deltav;
279 vmax = vmax + deltav;
280 }
281 }
282 }
c6541a0c 283 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
7fd59977 284 }
285 }
286 }
287
288 if (postponed || S != NewS) {
289 Draft_FaceInfo FI(NewS,Standard_True);
290 FI.RootFace(curFace);
291 myFMap.Bind(F,FI);
292 if (postponed) {
293 myFMap(F).ChangeCurve() = theCircle;
294 }
295 }
296
297 TopExp_Explorer expl(F,TopAbs_EDGE);
298 TopTools_MapOfShape MapOfE;
299 while (expl.More() && badShape.IsNull()) {
300 const TopoDS_Edge& edg = TopoDS::Edge(expl.Current());
301 if (!myEMap.IsBound(edg)) {
302 Standard_Boolean addedg = Standard_False;
303 Standard_Boolean addface = Standard_False;
304 TopoDS_Face OtherF;
305 // if (BRep_Tool::IsClosed(edg,F)) {
306 if (BRepTools::IsReallyClosed(edg,F)) {
307 addedg = Standard_True;
308 addface = Standard_False;
309 }
310 else {
0d969553 311 // Find the other face containing the edge.
7fd59977 312 TopTools_ListIteratorOfListOfShape it;
313 it.Initialize(myEFMap.FindFromKey(edg));
314 Standard_Integer nbother = 0;
315 while (it.More()) {
316 if (!it.Value().IsSame(F)) {
317 if (OtherF.IsNull()) {
318 OtherF = TopoDS::Face(it.Value());
319 }
320 nbother++;
321 }
322 it.Next();
323 }
324 if (nbother >=2) {
325 badShape = edg;
326 errStat = Draft_EdgeRecomputation;
327 }
328 else if (! OtherF.IsNull() &&
329 BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
330 addface= Standard_True;
331 addedg = Standard_True;
332 }
0d969553 333 else if (nbother == 0) {
7fd59977 334 // badShape = F;
335 }
336 }
337 if (addedg) {
338 if (postponed) {
339 myFMap(F).Add(OtherF);
340 }
341 Standard_Real f,l;
342 TopLoc_Location L;
343 Handle(Geom_Curve) C = BRep_Tool::Curve(edg,L,f,l);
344 C = Handle(Geom_Curve)::DownCast(C->Transformed(L));
345 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
346 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
347 }
348 Handle(Geom_Curve) NewC;
349 Draft_EdgeInfo EInf(Standard_True);
350 if(postponed) {
351 EInf.Add(F);
352 EInf.Add(OtherF);
353
0d969553 354 // find fixed point
7fd59977 355 Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
356 if (aLocalGeom.IsNull()) {
357 badShape = edg;
358 errStat = Draft_EdgeRecomputation;
359 }
360 else {
361 gp_Lin lin = aLocalGeom->Lin();
362 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
363 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
364 EInf.Tangent(ilipl.Point(1));
365 }
366 else {
367 badShape = edg;
368 errStat = Draft_EdgeRecomputation;
369 }
370 }
371 }
372 else {
373 NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
374 if (NewC.IsNull()) {
375 badShape = edg;
376 errStat = Draft_EdgeRecomputation;
377 }
378 }
379
380 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
381 if (!T.IsNull()) NewC = T->BasisCurve();
382 EInf.ChangeGeometry() = NewC;
383
384 EInf.RootFace(curFace);
385 myEMap.Bind(edg,EInf);
386 MapOfE.Add(edg);
387 if (addface) {
388 Standard_Boolean Fl = Flag;
389 Handle(Geom_Surface) alocalSurface = BRep_Tool::Surface(OtherF,Lo);
390 if (alocalSurface->DynamicType() ==
391 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
392 alocalSurface = Handle(Geom_RectangularTrimmedSurface)::
393 DownCast(alocalSurface)->BasisSurface();
394 }
395 Handle(Standard_Type) typS = alocalSurface->DynamicType();
396 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
397 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
398 if ( myFMap.IsBound(F)) {
399 if ( Flag == Standard_False && !postponed) {
400 myFMap.UnBind(F);
401 TopTools_MapIteratorOfMapOfShape itm(MapOfE);
402 for ( ; itm.More(); itm.Next())
403 myEMap.UnBind(TopoDS::Edge(itm.Key()));
404 }
405 }
406 }
407 InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
408 }
409 }
410 }
411 expl.Next();
412 }
413 return (badShape.IsNull());
414}
415
416
417//=======================================================================
418//function : Propagate
419//purpose :
420//=======================================================================
421
422Standard_Boolean Draft_Modification::Propagate ()
423{
424
425 if (!badShape.IsNull()) return Standard_False;
426
427 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
428
0d969553 429 // Set all edges and vertices of modified faces
7fd59977 430 TopoDS_Face F;
431 TopoDS_Edge E;
432 TopoDS_Vertex V;
433 TopExp_Explorer editer;
434 TopExp_Explorer vtiter;
435
436 while (itf.More()) {
437 const TopoDS_Face& Fc = itf.Key();
438
439 // Exploration of the edges of the face
440 editer.Init(Fc,TopAbs_EDGE);
441 while (editer.More()) {
442 E = TopoDS::Edge(editer.Current());
443
444 if (!myEMap.IsBound(E)) {
445 Draft_EdgeInfo EInf(Standard_True);
446 myEMap.Bind(E,EInf);
447 }
448 myEMap(E).Add(Fc);
449
450 // Exploration of the vertices of the edge
451 vtiter.Init(E,TopAbs_VERTEX);
452 while (vtiter.More()) {
453 V = TopoDS::Vertex(vtiter.Current());
454 if (!myVMap.IsBound(V)) {
455 Draft_VertexInfo VInf;
456 myVMap.Bind(V,VInf);
457 }
458
459 myVMap(V).Add(E);
460 myVMap(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
461 vtiter.Next();
462 }
463 editer.Next();
464 }
465 itf.Next();
466 }
467
468
469 TopExp_Explorer anc;
470 Standard_Boolean found;
471
0d969553 472 // Set edges containing modified vertices.
7fd59977 473
474 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
475
476 while (itv.More()) {
477 const TopoDS_Vertex& Vt = itv.Key();
478
479 // Exploration of the ancestors of the vertex
480 anc.Init(myShape,TopAbs_EDGE);
481
482 while (anc.More()) {
483 E = TopoDS::Edge(anc.Current());
484 vtiter.Init(E,TopAbs_VERTEX);
485 found = Standard_False;
486 while (vtiter.More()) {
487 if (Vt.IsSame(TopoDS::Vertex(vtiter.Current()))) {
488 found = Standard_True;
489 break;
490 }
491 vtiter.Next();
492 }
493 if (found) {
494 if (!myEMap.IsBound(E)) {
495 Draft_EdgeInfo EInf(Standard_False);
496 myEMap.Bind(E,EInf);
497 }
498 myVMap(Vt).Add(E);
499 myVMap(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
500 }
501 anc.Next();
502 }
503 itv.Next();
504 }
505
506
0d969553 507 // Set faces containing modified edges
7fd59977 508
509 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
510
511 while (ite.More()) {
512 const TopoDS_Edge& Ed = ite.Key();
513 TopTools_ListIteratorOfListOfShape it;
514 for (it.Initialize(myEFMap.FindFromKey(Ed)); it.More(); it.Next()) {
515 F = TopoDS::Face(it.Value());
516 if (!myFMap.IsBound(F)) {
517 TopLoc_Location L;
518 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
519 Handle(Geom_Surface) NewS =
520 Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
521
522 const Handle(Standard_Type)& typs = S->DynamicType();
523 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
524 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
525 Standard_Real umin,umax,vmin,vmax;
526 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
527 if (!Precision::IsNegativeInfinite(vmin) &&
528 !Precision::IsPositiveInfinite(vmax)) {
529 Standard_Real deltav = 10.*(vmax-vmin);
530 vmin = vmin - deltav;
531 vmax = vmax + deltav;
532 NewS =
c6541a0c 533 new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
7fd59977 534 }
535 }
536
537 Draft_FaceInfo FInf(NewS,Standard_False);
538 myFMap.Bind(F,FInf);
539 }
540 myEMap(Ed).Add(F);
541 }
542 ite.Next();
543 }
544
0d969553 545 // Try to add faces for free borders...
7fd59977 546 // JAG 09.11.95
547 ite.Initialize(myEMap);
548 for (; ite.More(); ite.Next()) {
549 Draft_EdgeInfo& Einf = myEMap(ite.Key());
550 if (Einf.NewGeometry() && Einf.Geometry().IsNull() &&
551 Einf.SecondFace().IsNull()) {
552
553 TopLoc_Location Loc;
554 Handle(Geom_Surface) S1 = BRep_Tool::Surface(Einf.FirstFace(),Loc);
555 S1 = Handle(Geom_Surface)::
556 DownCast(S1->Transformed(Loc.Transformation()));
557 Handle(Geom_Surface) S2;
558
559 Standard_Real f,l;
560 Handle(Geom_Curve) C = BRep_Tool::Curve(ite.Key(),Loc,f,l);
561 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
562 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
563 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
564 }
565 if (!S1->IsKind(STANDARD_TYPE(Geom_Plane))) {
566 if (C->IsKind(STANDARD_TYPE(Geom_Conic))) {
567 gp_Ax3 thePl(Handle(Geom_Conic)::DownCast(C)->Position());
568 S2 = new Geom_Plane(thePl);
569 }
570 else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
571 gp_Ax1 axis;
572 if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
573 axis = Handle(Geom_ElementarySurface)::DownCast
574 (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
575 BasisSurface())->Axis();
576 }
577 else {
578 axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
579 }
580 gp_Vec they(axis.Location(), C->Value(0.));
581 gp_Dir axz(axis.Direction().Crossed(they));
582 S2=new Geom_Plane(gp_Ax3(axis.Location(),axz,axis.Direction()));
583
584 }
585 else {
586 badShape = TopoDS::Edge(ite.Key());
587 errStat = Draft_EdgeRecomputation;
0d969553 588 break; // leave from for
7fd59977 589 }
590 }
0d969553 591 else { // on the plane
7fd59977 592 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo anewitv(myVMap);
593 while (anewitv.More()) {
594 Draft_VertexInfo& Vinf = myVMap(anewitv.Key());
595 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
596 if (Vinf.Edge().IsSame(ite.Key())) {
597 break;
598 }
599 }
600 if (Vinf.MoreEdge()) {
601 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
602 const TopoDS_Edge& edg = Vinf.Edge();
603 if (!edg.IsSame(ite.Key())) {
604 if (!myEMap(edg).FirstFace().IsSame(Einf.FirstFace()) &&
605 (myEMap(edg).SecondFace().IsNull() ||
606 !myEMap(edg).SecondFace().IsSame(Einf.FirstFace()))) {
607 break;
608 }
609 }
610 }
611 if (Vinf.MoreEdge()) {
612 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
613 Handle(GeomAdaptor_HCurve) HCur;
614 gp_Vec Direc;
615 C2 = Handle(Geom_Curve)::DownCast
616 (C2->Transformed(Loc.Transformation()));
617 if (C2->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
618 C2 = Handle(Geom_TrimmedCurve)::DownCast(C2)->BasisCurve();
619 }
620 if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
621 Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
622 HCur = new GeomAdaptor_HCurve(C2);
623
624 }
625 else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
626 Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
627 HCur = new GeomAdaptor_HCurve(C);
628 }
629 else {
630 badShape = TopoDS::Edge(ite.Key());
631 errStat = Draft_EdgeRecomputation;
0d969553 632 break; // leave from while
7fd59977 633 }
634 Adaptor3d_SurfaceOfLinearExtrusion SLE(HCur,Direc);
635 switch(SLE.GetType()){
636
637 case GeomAbs_Plane :
638 {
639 S2 = new Geom_Plane(SLE.Plane());
640 }
641 break;
642 case GeomAbs_Cylinder :
643 {
644 S2 = new Geom_CylindricalSurface(SLE.Cylinder());
645 }
646 break;
647 default :
648 {
649 S2 = new Geom_SurfaceOfLinearExtrusion(HCur->ChangeCurve().
650 Curve(),
651 Direc);
652 }
653 break;
654 }
655
656 }
657 else {
658 badShape = TopoDS::Edge(ite.Key());
659 errStat = Draft_EdgeRecomputation;
0d969553 660 break; // leave from while
7fd59977 661 }
662 break;
663 }
664 anewitv.Next();
665 }
666 }
667
668 if (badShape.IsNull()) {
669 BRep_Builder B;
670 TopoDS_Face TheNewFace;
671 B.MakeFace(TheNewFace,S2,Precision::Confusion());
672 Einf.Add(TheNewFace);
673 Draft_FaceInfo FI(S2,Standard_False);
674 myFMap.Bind(TheNewFace,FI);
675 }
676 else {
0d969553 677 break; // leave from for
7fd59977 678 }
679 // Fin JAG 09.11.95
680 }
681 }
682 return (badShape.IsNull());
683}
684
685
686
687
688//=======================================================================
689//function : Perform
690//purpose :
691//=======================================================================
692
693void Draft_Modification::Perform ()
694{
695 if (!badShape.IsNull()) Standard_ConstructionError::Raise();
696
697 if (!myComp) {
698 myComp = Standard_True;
699 if (!Propagate()) {
700 return;
701 }
702
0d969553 703 // Calculate eventual faces
7fd59977 704
705 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
706 while (itf.More()) {
707 Draft_FaceInfo& Finf = myFMap(itf.Key());
708 if (Finf.NewGeometry() && Finf.Geometry().IsNull()) {
709 const TopoDS_Face& F1 = Finf.FirstFace();
710 const TopoDS_Face& F2 = Finf.SecondFace();
711
712 if (F1.IsNull() || F2.IsNull()) {
713 errStat = Draft_FaceRecomputation;
714 badShape = TopoDS::Face(itf.Key());
715 return;
716 }
717 Handle(Geom_Surface) S1 = myFMap(F1).Geometry();
718 Handle(Geom_Surface) S2 = myFMap(F2).Geometry();
719 if (S1.IsNull() || S2.IsNull()) {
720 errStat = Draft_FaceRecomputation;
721 badShape = TopoDS::Face(itf.Key());
722 return;
723 }
724 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
725 S1 = Handle(Geom_RectangularTrimmedSurface)::
726 DownCast(S1)->BasisSurface();
727 }
728 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
729 S2 = Handle(Geom_RectangularTrimmedSurface)::
730 DownCast(S2)->BasisSurface();
731 }
732 Handle(Geom_Plane) P1 = Handle(Geom_Plane)::DownCast(S1);
733 Handle(Geom_Plane) P2 = Handle(Geom_Plane)::DownCast(S2);
734 if (P1.IsNull() || P2.IsNull()) {
735 errStat = Draft_FaceRecomputation;
736 badShape = TopoDS::Face(itf.Key());
737 return;
738 }
739 gp_Pln pp1 = P1->Pln();
740 gp_Pln pp2 = P2->Pln();
741 IntAna_QuadQuadGeo i2p(pp1,pp2,
742 Precision::Angular(),Precision::Confusion());
743 if (!i2p.IsDone() || i2p.TypeInter() != IntAna_Line) {
744 errStat = Draft_FaceRecomputation;
745 badShape = TopoDS::Face(itf.Key());
746 return;
747 }
748
749 gp_Dir extrdir = i2p.Line(1).Direction();
750
0d969553 751 // Preserve the same direction as the base face
7fd59977 752 Handle(Geom_Surface) RefSurf =
753 BRep_Tool::Surface(TopoDS::Face(itf.Key()));
754 if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
755 RefSurf =
756 Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
757 ->BasisSurface();
758 }
759 gp_Dir DirRef;
760
761 if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
762 gp_Ax3 AxeRef =
763 Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
764 ->Cylinder().Position();
765 DirRef = AxeRef.Direction();
766 }
767 else if (RefSurf->DynamicType() ==
768 STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
769 DirRef =
770 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)
771 ->Direction();
772 }
773
774 if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
775
0d969553
Y
776 // it is possible to accelerate speed by storing the info during
777 // InternalAdd --> modification of FaceInfo to preserve the circle
7fd59977 778
779 Handle(Geom_Circle) CCir =
780 Handle(Geom_Circle)::DownCast(Finf.Curve());
781 Handle(Geom_Surface) NewS =
782 new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);
783
784 Standard_Real umin, umax, vmin, vmax;
785 BRepTools::UVBounds(TopoDS::Face(itf.Key()),umin,umax,vmin,vmax);
786 if (!Precision::IsNegativeInfinite(vmin) &&
787 !Precision::IsPositiveInfinite(vmax)) {
788 Standard_Real deltav = 2.*(vmax-vmin);
789 vmin = vmin - deltav;
790 vmax = vmax + deltav;
791 }
792
0d969553 793 // very temporary
7fd59977 794 else {
795 vmax = 300;
796 vmin = -300;
797 }
798
c6541a0c 799 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*M_PI,vmin,vmax);
7fd59977 800 Finf.ChangeGeometry() = NewS;
801 }
802 itf.Next();
803 }
804
0d969553 805 // Calculate new edges.
7fd59977 806
807 Handle(Geom_Surface) S1,S2;
808 Handle(Geom_Curve) C, newC;
809 Standard_Real f,l;
810 TopLoc_Location L;
811 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
812
813 while (ite.More()) {
814 Draft_EdgeInfo& Einf = myEMap(ite.Key());
815
816 const TopoDS_Edge& theEdge = TopoDS::Edge(ite.Key());
817
818 C = BRep_Tool::Curve(theEdge,L,f,l);
819 C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
820
821 if (Einf.NewGeometry() && Einf.Geometry().IsNull()) {
822 gp_Pnt ptfixe;
823 if (!Einf.IsTangent(ptfixe)) {
824 const TopoDS_Face& FirstFace = Einf.FirstFace();
825 const TopoDS_Face& SecondFace = Einf.SecondFace();
826
827 S1 = myFMap(FirstFace).Geometry();
828 S2 = myFMap(SecondFace).Geometry();
829
830 Standard_Integer detrompeur = 0;
831
0d969553 832 // Return FirstVertex and the tangent at this point.
7fd59977 833 TopoDS_Vertex FV = TopExp::FirstVertex(theEdge);
834 TopoDS_Vertex LV = TopExp::LastVertex(theEdge);
835 Standard_Real pmin = 0.;
836 Standard_Real prmfv = BRep_Tool::Parameter(FV,ite.Key());
837 Standard_Real prmlv = BRep_Tool::Parameter(LV,ite.Key());
838 gp_Pnt pfv, plv;
839 gp_Vec d1fv,d1lv, newd1;
840 C->D1(prmfv,pfv,d1fv);
841 C->D1(prmlv,plv,d1lv);
842
843 Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
844 Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
845
0d969553 846 //Pass the tolerance of the face to project
7fd59977 847 GeomAPI_ProjectPointOnSurf proj1 (pfv, S1, TolF1);
848 GeomAPI_ProjectPointOnSurf proj2 (plv, S1, TolF1);
849 GeomAPI_ProjectPointOnSurf proj3 (pfv, S2, TolF2);
850 GeomAPI_ProjectPointOnSurf proj4 (plv, S2, TolF2);
851
852 if (proj1.IsDone () && proj2.IsDone ()) {
853 if(proj1.LowerDistance()<= Precision::Confusion() &&
854 proj2.LowerDistance()<= Precision::Confusion()) {
855 detrompeur = 1;
856 }
857 }
858
859 if (proj3.IsDone () && proj4.IsDone ()) {
860 if(proj3.LowerDistance() <= Precision::Confusion() &&
861 proj4.LowerDistance() <= Precision::Confusion()) {
862 detrompeur = 2;
863 }
864 }
865
866 gp_Dir TheDirExtr;
867 gp_Ax3 Axis;
868 Handle(Geom_Curve) TheNewCurve;
869 Standard_Boolean KPart = Standard_False;
870
871 if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
872 S1 = Handle(Geom_RectangularTrimmedSurface)::
873 DownCast(S1)->BasisSurface();
874 }
875 if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
876 S2 = Handle(Geom_RectangularTrimmedSurface)::
877 DownCast(S2)->BasisSurface();
878 }
879
0d969553 880 Standard_Boolean PC1 = Standard_True; // KPart on S1
7fd59977 881 if (S1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
882 S2->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
883 KPart = Standard_True;
884 Axis = Handle(Geom_Plane)::DownCast(S2)->Position();
885 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
886 DownCast(S1)->BasisCurve();
887 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
888 DownCast(S1)->Direction();
889 }
890 else if (S2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
891 S1->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
892 KPart = Standard_True;
893 PC1 = Standard_False;
894 Axis = Handle(Geom_Plane)::DownCast(S1)->Position();
895 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
896 DownCast(S2)->BasisCurve();
897 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
898 DownCast(S2)->Direction();
899 }
900 Handle(Geom_Circle) aCirc ;
0d969553 901 if ( KPart) { // very temporary on circles !!!
7fd59977 902 aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
903 if (aCirc.IsNull())
904 KPart = Standard_False;
905 else
906 {
907 gp_Dir AxofCirc = aCirc->Position().Direction();
908 if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
909 KPart = Standard_True;
910 else
911 KPart = Standard_False;
912 }
913 }
914
915 Standard_Integer imin;
916 GeomInt_IntSS i2s;
917 if ( KPart) {
0d969553 918 // direct calculation of NewC
7fd59977 919 Standard_Real aLocalReal =
920 gp_Vec(aCirc->Circ().Location(),Axis.Location()).
921 Dot(Axis.Direction());
922 Standard_Real Cos = TheDirExtr.Dot(Axis.Direction());
923 gp_Vec VV = ( aLocalReal / Cos) * TheDirExtr;
924 newC = Handle(Geom_Curve)::DownCast(TheNewCurve->Translated(VV));
0d969553 925 // it is possible to calculate PCurve
7fd59977 926 Handle(Geom2d_Line) L2d
927 = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
928 gp::DX2d());
929
930 if ( PC1)
931 Einf.ChangeFirstPC() = L2d;
932 else
933 Einf.ChangeSecondPC() = L2d;
934 }
935 else {
936 S1 = myFMap(Einf.FirstFace()).Geometry();
937 S2 = myFMap(Einf.SecondFace()).Geometry();
938
0d969553
Y
939
940 // PCurves are not calculated immediately for 2 reasons:
941 // 1 - If ProjLib should make an Approx, it is stupid to approximate the
942 // entire intersection curve.
943 // 2 - Additionally, if YaRev, there is a risk to not be SameRange.
7fd59977 944 i2s.Perform(S1,S2,Precision::Confusion(),
945 Standard_True,Standard_False,Standard_False);
946
947 if (!i2s.IsDone() || i2s.NbLines() <= 0) {
948 errStat = Draft_EdgeRecomputation;
949 badShape = TopoDS::Edge(ite.Key());
950 return;
951 }
952
953 Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
954 GeomAdaptor_Curve TheCurve;
955
956 Standard_Integer i,j; //,jmin;
957
958 if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
959 {
960 imin = 0;
961 for (i=1; i<= i2s.NbLines(); i++) {
962 TheCurve.Load(i2s.Line(i));
963 Extrema_ExtPC myExtPC(pfv,TheCurve);
964
965 Standard_Real locpmin = 0.;
966 if (myExtPC.IsDone()) {
967 if(myExtPC.NbExt() >= 1) {
968 Dist2Min = myExtPC.SquareDistance(1);
969 locpmin = myExtPC.Point(1).Parameter();
970 }
08cd2f6b 971 if(myExtPC.NbExt() == 2 && Dist2Min > Precision::SquareConfusion()) {
0d969553
Y
972 //to avoid incorrectly choosing the image
973 //of the first vertex of the initial edge
7fd59977 974 Standard_Real d1_2 = myExtPC.SquareDistance(1);
975 Standard_Real d2_2 = myExtPC.SquareDistance(2);
976 if(d1_2 > 1.21*d2_2) {
977 Dist2Min = myExtPC.SquareDistance(2);
978 locpmin = myExtPC.Point(2).Parameter();
979 }
980 else if(d2_2 > 1.21*d1_2) {
981 Dist2Min = myExtPC.SquareDistance(1);
982 locpmin = myExtPC.Point(1).Parameter();
983 }
984 else {
985 Standard_Real pfvpar = myExtPC.Point(1).Parameter();
986 Standard_Real plvpar = myExtPC.Point(2).Parameter();
987 newC = i2s.Line(i);
988
989 gp_Pnt pfvprim, plvprim;
990
991 newC->D0(pfvpar,pfvprim);
992 newC->D0(plvpar,plvprim);
993
994 Handle(Geom_Surface) theSurf;
995 if(detrompeur == 1) {
996 if(S1->DynamicType() ==
997 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
998 S1 = Handle(Geom_RectangularTrimmedSurface)::
999 DownCast(S1)->BasisSurface();
1000 theSurf = S1;
1001
1002 }
1003 else if(detrompeur == 2) {
1004 if(S2->DynamicType() ==
1005 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
1006 S2 = Handle(Geom_RectangularTrimmedSurface)::
1007 DownCast(S2)->BasisSurface();
1008 theSurf = S2;
1009 }
1010 if(detrompeur != 0 && detrompeur != 4) {
1011 Standard_Real ul, vl, uf, vf;
1012 Standard_Real ufprim, ulprim, vfprim, vlprim;
1013
1014 if(theSurf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1015 gp_Pln pl = Handle(Geom_Plane)::DownCast(S2)->Pln();
1016 ElSLib::Parameters(pl, plv, ul, vl);
1017 ElSLib::Parameters(pl, pfv, uf, vf);
1018 ElSLib::Parameters(pl, plvprim, ulprim, vlprim);
1019 ElSLib::Parameters(pl, pfvprim, ufprim, vfprim);
1020 }
1021 else if(theSurf->DynamicType() ==
1022 STANDARD_TYPE(Geom_CylindricalSurface)) {
1023 gp_Cylinder cy = Handle(Geom_CylindricalSurface)
1024 ::DownCast(S2)->Cylinder();
1025 ElSLib::Parameters(cy, plv, ul, vl);
1026 ElSLib::Parameters(cy, pfv, uf, vf);
1027 ElSLib::Parameters(cy, plvprim, ulprim, vlprim);
1028 ElSLib::Parameters(cy, pfvprim, ufprim, vfprim);
1029 }
1030 else detrompeur = 4;
1031
1032 if(detrompeur == 1 || detrompeur == 2) {
1033 gp_Vec2d v1((ul-ufprim), (vl-vfprim));
1034 gp_Vec2d norm((vf-vfprim), (ufprim-uf));
1035 gp_Vec2d v2((ulprim-ufprim), (vlprim-vfprim));
1036 if( (v1.Dot(norm))*(v2.Dot(norm)) < 0) {
1037 Dist2Min = myExtPC.SquareDistance(2);
1038 locpmin = myExtPC.Point(2).Parameter();
1039 }
1040 }
1041 }
1042 }
1043 }
1044 if (myExtPC.NbExt() == 1 || myExtPC.NbExt() > 2 || detrompeur ==4) {
1045 Dist2Min = myExtPC.SquareDistance(1);
1046 locpmin = myExtPC.Point(1).Parameter();
1047 for (j=2; j<=myExtPC.NbExt(); j++) {
1048 Dist2 = myExtPC.SquareDistance(j);
1049 if (Dist2 < Dist2Min) {
1050 Dist2Min = Dist2;
1051 locpmin = myExtPC.Point(j).Parameter();
1052 }
1053 }
1054 }
1055 else if(myExtPC.NbExt() < 1){
1056 Standard_Real dist1_2,dist2_2;
1057 gp_Pnt p1b,p2b;
1058 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
1059 if (dist1_2 < dist2_2) {
1060 Dist2Min = dist1_2;
1061 locpmin = TheCurve.FirstParameter();
1062 }
1063 else {
1064 Dist2Min = dist2_2;
1065 locpmin = TheCurve.LastParameter();
1066 }
1067 }
1068
1069 if (Dist2Min < Glob2Min) {
1070 Glob2Min = Dist2Min;
1071 imin = i;
1072 pmin = locpmin;
1073 }
1074 }
1075 }
1076 if (imin == 0) {
1077 errStat = Draft_EdgeRecomputation;
1078 badShape = TopoDS::Edge(ite.Key());
1079 return;
1080 }
1081
1082 newC = i2s.Line(imin);
1083
1084 newC->D1(pmin,pfv,newd1);
1085 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1086
1087 if (YaRev)
1088 newC->Reverse();
1089
1090 if (i2s.HasLineOnS1(imin)) {
1091 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1092 if ( YaRev)
1093 Einf.ChangeFirstPC()->Reverse();
1094 }
1095
1096 if (i2s.HasLineOnS2(imin)) {
1097 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1098 if ( YaRev)
1099 Einf.ChangeSecondPC()->Reverse();
1100 }
1101 } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
1102 else // i2s.Line(1) is BSplineCurve
1103 {
1104 //Find the first curve to glue
1105 TColGeom_SequenceOfCurve Candidates;
1106 if (S1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface) ||
1107 S1->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
1108 {
1109 for (i = 1; i <= i2s.NbLines(); i++)
1110 {
1111 Handle( Geom_Curve ) aCurve = i2s.Line(i);
1112 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1113 GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
1114 Standard_Real U, V;
1115 projector.LowerDistanceParameters( U, V );
c6541a0c 1116 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
7fd59977 1117 Candidates.Append( aCurve );
1118 else
1119 {
1120 Pnt = aCurve->Value( aCurve->LastParameter() );
1121 projector.Init( Pnt, S1, Precision::Confusion() );
1122 projector.LowerDistanceParameters( U, V );
c6541a0c 1123 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
7fd59977 1124 {
1125 aCurve->Reverse();
1126 Candidates.Append( aCurve );
1127 }
1128 }
1129 }
1130
1131 if(Candidates.Length() == 0)
1132 {
1133// errStat = Draft_EdgeRecomputation;
1134// badShape = TopoDS::Edge(ite.Key());
1135// return;
1136 for (i = 1; i <= i2s.NbLines(); i++)
1137 Candidates.Append( i2s.Line(i) );
1138 }
1139 }
1140 else
1141 {
1142 for (i = 1; i <= i2s.NbLines(); i++)
1143 Candidates.Append( i2s.Line(i) );
1144 }
1145
1146 Handle( Geom_Curve ) FirstCurve;
1147 if (Candidates.Length() > 1)
1148 {
1149 Dist2Min = RealLast();
1150 for (i = 1; i <= Candidates.Length(); i++)
1151 {
1152 Handle( Geom_Curve ) aCurve = Candidates(i);
1153 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1154 Dist2 = Pnt.SquareDistance( pfv );
1155 if (Dist2 < Dist2Min)
1156 {
1157 Dist2Min = Dist2;
1158 FirstCurve = aCurve;
1159 }
1160 }
1161 }
1162 else
1163 FirstCurve = Candidates(1);
1164
1165 //Glueing
1166 TColGeom_SequenceOfCurve Curves;
1167 for (i = 1; i <= i2s.NbLines(); i++)
1168 if (FirstCurve != i2s.Line(i))
1169 Curves.Append( i2s.Line(i) );
1170
1171 TColGeom_SequenceOfCurve ToGlue;
1172 gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
1173 Standard_Boolean added = Standard_True;
1174 while (added)
1175 {
1176 added = Standard_False;
1177 for (i = 1; i <= Curves.Length(); i++)
1178 {
1179 Handle( Geom_Curve ) aCurve = Curves(i);
1180 gp_Pnt pfirst, plast;
1181 pfirst = aCurve->Value( aCurve->FirstParameter() );
1182 plast = aCurve->Value( aCurve->LastParameter() );
1183 if (pfirst.Distance( EndPoint ) <= Precision::Confusion())
1184 {
1185 ToGlue.Append( aCurve );
1186 EndPoint = plast;
1187 Curves.Remove(i);
1188 added = Standard_True;
1189 break;
1190 }
1191 if (plast.Distance( EndPoint ) <= Precision::Confusion())
1192 {
1193 aCurve->Reverse();
1194 ToGlue.Append( aCurve );
1195 EndPoint = pfirst;
1196 Curves.Remove(i);
1197 added = Standard_True;
1198 break;
1199 }
1200 }
1201 }
1202
1203 if (FirstCurve.IsNull()) {
1204 errStat = Draft_EdgeRecomputation;
1205 badShape = TopoDS::Edge(ite.Key());
1206 return;
1207 }
1208
1209 GeomConvert_CompCurveToBSplineCurve Concat( Handle(Geom_BSplineCurve)::DownCast(FirstCurve) );
1210 for (i = 1; i <= ToGlue.Length(); i++)
1211 Concat.Add( Handle(Geom_BSplineCurve)::DownCast(ToGlue(i)), Precision::Confusion(), Standard_True );
1212
1213 newC = Concat.BSplineCurve();
1214
1215 TheCurve.Load( newC );
1216 Extrema_ExtPC myExtPC( pfv, TheCurve );
1217 Dist2Min = RealLast();
1218 for (i = 1; i <= myExtPC.NbExt(); i++)
1219 {
1220 Dist2 = myExtPC.SquareDistance(i);
1221 if (Dist2 < Dist2Min)
1222 {
1223 Dist2Min = Dist2;
1224 pmin = myExtPC.Point(i).Parameter();
1225 }
1226 }
1227
1228 newC->D1(pmin,pfv,newd1);
1229 Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.;
1230
1231 if (YaRev)
1232 newC->Reverse();
1233 /*
1234 if (i2s.HasLineOnS1(imin)) {
1235 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1236 if ( YaRev)
1237 Einf.ChangeFirstPC()->Reverse();
1238 }
1239
1240 if (i2s.HasLineOnS2(imin)) {
1241 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1242 if ( YaRev)
1243 Einf.ChangeSecondPC()->Reverse();
1244 }
1245 */
1246 } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
1247
1248 Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
0d969553 1249 } // End step KPart
7fd59977 1250 }
0d969553 1251 else { // case of tangency
7fd59977 1252 const TopoDS_Face& F1 = Einf.FirstFace();
1253 const TopoDS_Face& F2 = Einf.SecondFace();
1254
1255 Handle(Geom_Surface) aLocalS1 = myFMap(F1).Geometry();
1256 Handle(Geom_Surface) aLocalS2 = myFMap(F2).Geometry();
1257 if (aLocalS1.IsNull() || aLocalS2.IsNull()) {
1258 errStat = Draft_EdgeRecomputation;
1259 badShape = TopoDS::Edge(ite.Key());
1260 return;
1261 }
1262 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1263 aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
1264 DownCast(aLocalS1)->BasisSurface();
1265 }
1266 if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1267 aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
1268 DownCast(aLocalS2)->BasisSurface();
1269 }
1270
1271 gp_Dir dirextr;
1272 //Standard_Boolean dirfound = Standard_False;
1273 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1274 gp_Cylinder cyl =
1275 Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
1276 dirextr = cyl.Axis().Direction();
1277 //dirfound = Standard_True;
0d969553 1278 // see direction...
7fd59977 1279
1280 }
1281 else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1282 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1283 DownCast(aLocalS1)->Direction();
1284 //dirfound = Standard_True;
0d969553 1285 // see direction...
7fd59977 1286
0d969553 1287 // Here it is possible to calculate PCurve.
7fd59977 1288 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1289 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS1);
1290 Handle(Geom_Circle) GCir =
1291 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1292 if ( !GCir.IsNull()) {
1293 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1294 Handle(Geom2d_Line) PC1 =
1295 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1296 Einf.ChangeFirstPC() = PC1;
1297 }
1298 }
1299
1300 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1301 gp_Cylinder cyl =
1302 Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
1303 dirextr = cyl.Axis().Direction();
0d969553
Y
1304 // dirfound = Standard_True;
1305 // see direction...
7fd59977 1306
1307 }
1308 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1309 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1310 DownCast(aLocalS2)->Direction();
0d969553
Y
1311 // dirfound = Standard_True;
1312 // see direction...
7fd59977 1313
0d969553 1314 // Here it is possible to calculate PCurve.
7fd59977 1315 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1316 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS2);
1317 Handle(Geom_Circle) GCir =
1318 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1319 if ( !GCir.IsNull()) {
1320 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1321 Handle(Geom2d_Line) PC2 =
1322 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1323 Einf.ChangeSecondPC() = PC2;
1324 }
1325 }
1326 newC = new Geom_Line(ptfixe,dirextr);
1327
1328 gp_Pnt pfv;
1329 gp_Vec d1fv,newd1;
1330 C->D1(0.,pfv,d1fv);
1331 newC->D1(0.,pfv,newd1);
1332 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1333 if (YaRev) {
1334 newC->Reverse();
1335 if(!Einf.FirstPC().IsNull()) {
1336 Einf.ChangeFirstPC()->Reverse();
1337 }
1338 if(!Einf.SecondPC().IsNull()) {
1339 Einf.ChangeSecondPC()->Reverse();
1340 }
1341 }
1342 }
1343
1344 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
1345 if (!T.IsNull()) newC = T->BasisCurve();
1346 Einf.ChangeGeometry() = newC;
1347 }
1348 else if (!Einf.NewGeometry()){
0d969553 1349 // set existing curve 3D
7fd59977 1350 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
1351 if (!T.IsNull()) C = T->BasisCurve();
1352 Einf.ChangeGeometry() = C;
1353 }
1354 ite.Next();
1355 }
1356
0d969553 1357 // Calculate new vertices.
7fd59977 1358
1359 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
1360
1361 Handle(GeomAdaptor_HCurve) HAC = new GeomAdaptor_HCurve;
1362 Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface;
1363
1364 while (itv.More()) {
1365 GeomAdaptor_Curve AC;
1366 GeomAdaptor_Surface AS;
1367
1368 Draft_VertexInfo& Vinf = myVMap(itv.Key());
1369 if (!Choose(myFMap,myEMap,itv.Key(),Vinf,AC,AS)) {
1370
0d969553 1371// no concerted edge => alignment of two consecutive edges.
7fd59977 1372 gp_Pnt pvt;
1373 Vinf.ChangeGeometry() = pvt;
1374 Vinf.InitEdgeIterator();
1375 if (Vinf.MoreEdge()) {
1376 const TopoDS_Edge& Edg1 = Vinf.Edge();
1377 //const Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1378 Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1379 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1380 //Einf1.Geometry()->D0(Vinf.Parameter(Edg1), pvt);
1381 GeomAPI_ProjectPointOnCurve Projector( vtori, Einf1.Geometry() ); //patch
1382 pvt = Projector.NearestPoint();
1383
1384#ifdef DEB
1385 static Standard_Integer VertexRecomp = 1;
1386 if (VertexRecomp!=0) {
1387 cout << "pori :" << vtori.X() << " " << vtori.Y() << " " << vtori.Z() << endl;
1388 cout << " Edg 1 :" << Vinf.Parameter(Edg1) << endl;
1389 cout << "pvt :" << pvt.X() << " " << pvt.Y() << " " << pvt.Z() << endl;
1390 }
1391#endif
1392
1393 Standard_Real dion=pvt.SquareDistance(vtori);
1394 Vinf.NextEdge();
1395 if (Vinf.MoreEdge()) {
1396 const TopoDS_Edge& Edg2 = Vinf.Edge();
1397 //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1398 Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1399// Standard_Real f;
1400 gp_Pnt opvt;
1401 Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
1402
1403#ifdef DEB
1404 if (VertexRecomp!=0) {
1405 cout << " Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << endl;
1406 cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << endl;
1407 }
1408#endif
1409
1410 if (opvt.SquareDistance(vtori) < dion) {
1411 pvt = opvt;
1412 }
1413 //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
1414 Standard_Integer done;
1415 Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
1416 if (done != 0)
1417 {
1418 S1 = myFMap(Einf2.FirstFace()).Geometry();
1419 S2 = myFMap(Einf2.SecondFace()).Geometry();
1420 Vinf.ChangeParameter(Edg2) = SmartParameter( Einf2, BRep_Tool::Tolerance(Edg2), pvt, done, S1, S2 );
1421 }
1422 else
1423 Vinf.ChangeParameter(Edg2) = param;
1424 }
1425
1426 Vinf.ChangeGeometry() = pvt;
1427 //Vinf.ChangeParameter(Edg1) = Parameter(Einf1.Geometry(), pvt);
1428 Standard_Integer done;
1429 Standard_Real param = Parameter(Einf1.Geometry(), pvt, done);
1430 if (done != 0)
1431 {
1432 S1 = myFMap(Einf1.FirstFace()).Geometry();
1433 S2 = myFMap(Einf1.SecondFace()).Geometry();
1434 Vinf.ChangeParameter(Edg1) = SmartParameter( Einf1, BRep_Tool::Tolerance(Edg1), pvt, done, S1, S2 );
1435 }
1436 else
1437 Vinf.ChangeParameter(Edg1) = param;
1438 itv.Next();
1439 continue;
1440 }
1441
1442
1443 errStat = Draft_VertexRecomputation;
1444 badShape = TopoDS::Vertex(itv.Key());
1445 return;
1446 }
1447
1448 IntCurveSurface_HInter myintcs;
1449 HAC->Set(AC);
1450 HAS->Set(AS);
1451 myintcs.Perform(HAC,HAS);
1452
1453 if (!myintcs.IsDone()) {
1454 errStat = Draft_VertexRecomputation;
1455 badShape = TopoDS::Vertex(itv.Key());
1456 return;
1457 }
1458
1459 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1460 gp_Pnt pvt;
1461
1462 Standard_Integer nbsol = myintcs.NbPoints();
1463 if (nbsol <= 0)
1464 {
1465 Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
1466
1467 if(!extr.IsDone() || extr.NbExt() == 0) {
1468 errStat = Draft_VertexRecomputation;
1469 badShape = TopoDS::Vertex(itv.Key());
1470 return;
1471 }
1472
1473
1474 Standard_Real disref = RealLast();
1475 Standard_Integer iref = 0;
1476 Extrema_POnCurv Pc;
1477 Extrema_POnSurf Ps;
1478 for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
1479 {
1480 extr.Points( i, Pc, Ps );
1481 Standard_Real distemp = Pc.Value().SquareDistance(vtori);
1482 if ( distemp < disref)
1483 {
1484 disref = distemp;
1485 iref = i;
1486 }
1487 }
1488 extr.Points( iref, Pc, Ps );
1489 pvt = Pc.Value();
1490 }
1491 else
1492 {
1493 Standard_Real disref = RealLast();
1494 Standard_Integer iref = 0;
1495 for (Standard_Integer i = 1; i <= nbsol; i++)
1496 {
1497 Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
1498 if ( distemp < disref)
1499 {
1500 disref = distemp;
1501 iref = i;
1502 }
1503 }
1504 pvt = myintcs.Point(iref).Pnt();
1505 }
1506
1507 Vinf.ChangeGeometry() = pvt;
1508
1509 for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
1510 const TopoDS_Edge& Edg = Vinf.Edge();
1511 //const Draft_EdgeInfo& Einf = myEMap(Edg);
1512 Draft_EdgeInfo& Einf = myEMap(Edg);
1513 //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
1514 Standard_Integer done;
1515 Standard_Real param = Parameter(Einf.Geometry(), pvt, done);
1516 if (done != 0)
1517 {
1518 S1 = myFMap(Einf.FirstFace()).Geometry();
1519 S2 = myFMap(Einf.SecondFace()).Geometry();
1520 Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
1521 }
1522 else
1523 Vinf.ChangeParameter(Edg) = param;
1524 }
1525 itv.Next();
1526 }
1527 }
1528
0d969553 1529 // small loop of validation/protection
7fd59977 1530
1531 for (Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
1532 ite.More(); ite.Next()) {
1533 const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
1534
1535 TopoDS_Vertex Vf,Vl;
1536 TopExp::Vertices(edg,Vf,Vl);
1537 if (edg.Orientation() == TopAbs_REVERSED) {
1538 Vf.Reverse();
1539 Vl.Reverse();
1540 }
1541 Standard_Real pf,pl,tolerance;
1542 if (!NewParameter(Vf,edg,pf,tolerance)) {
1543 pf = BRep_Tool::Parameter(Vf,edg);
1544 }
1545 if (!NewParameter(Vl,edg,pl,tolerance)) {
1546 pl = BRep_Tool::Parameter(Vl,edg);
1547 }
1548 if (pl <= pf) {
1549// const Handle(Geom_Curve) gc=ite.Value().Geometry();
1550// if (!gc.IsNull()) {
1551// pl = gc->LastParameter();
1552// pf = gc->FirstParameter();
1553// }
1554 Handle( Geom_Curve ) theCurve = myEMap(edg).Geometry();
1555 if (theCurve->IsClosed())
1556 {
1557 // pf >= pl
1558 Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
1559 Standard_Real pconf = Precision::PConfusion();
1560 if (Abs( pf - LastPar ) <= pconf)
1561 pf = FirstPar;
1562 else if (Abs( pl - FirstPar ) <= pconf)
1563 pl = LastPar;
1564
1565 if(pl <= pf) {
1566 pl += (LastPar-FirstPar);
1567 }
1568
1569 }
1570 if (pl <= pf) {
1571 errStat = Draft_EdgeRecomputation;
1572 badShape = TopoDS::Edge(ite.Key());
1573 return;
1574 }
1575 }
1576 if (myVMap.IsBound( Vf ))
1577 myVMap(Vf).ChangeParameter(edg) = pf;
1578 if (myVMap.IsBound( Vl ))
1579 myVMap(Vl).ChangeParameter(edg) = pl;
1580 }
1581}
1582
1583
1584
1585//=======================================================================
1586//function : NewSurface
1587//purpose :
1588//=======================================================================
1589
1590Handle(Geom_Surface) Draft_Modification::NewSurface
1591 (const Handle(Geom_Surface)& S,
1592 const TopAbs_Orientation Oris,
1593 const gp_Dir& Direction,
1594 const Standard_Real Angle,
1595 const gp_Pln& NeutralPlane)
1596{
1597 Handle(Geom_Surface) NewS;
1598
1599 Handle(Standard_Type) TypeS = S->DynamicType();
1600
1601 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1602 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1603 gp_Ax1 Axe;
1604 Standard_Real Theta;
1605 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1606 if ( Abs(Theta) > Precision::Angular()) {
1607 NewS = Handle(Geom_Surface)::DownCast(S->Rotated(Axe,Theta));
1608 }
1609 else {
1610 NewS = S;
1611 }
1612 }
1613 }
1614 else if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1615 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1616 if (Abs(testdir) <= 1.-Precision::Angular()) {
1617#ifdef DEB
1618 cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << endl;
1619#endif
1620 return NewS;
1621 }
1622 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1623 testdir = Direction.Dot(Cy.Axis().Direction());
1624 if (Abs(testdir) <= 1.-Precision::Angular()) {
1625#ifdef DEB
1626 cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << endl;
1627#endif
1628 return NewS;
1629 }
1630 if (Abs(Angle) > Precision::Angular()) {
1631 IntAna_QuadQuadGeo i2s;
1632 i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
1633 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1634#ifdef DEB
1635 cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
1636#endif
1637 return NewS;
1638 }
1639 gp_Ax3 axcone = Cy.Position();
0d969553 1640 // Pb : Where is the material???
7fd59977 1641 Standard_Real alpha = Angle;
1642 Standard_Boolean direct(axcone.Direct());
1643 if ((direct && Oris == TopAbs_REVERSED) ||
1644 (!direct && Oris == TopAbs_FORWARD)) {
1645 alpha = -alpha;
1646 }
1647
1648 gp_Pnt Center = i2s.Circle(1).Location();
1649 if (testdir <0.) {
1650 alpha = -alpha;
1651 }
1652 Standard_Real Z = ElCLib::LineParameter(Cy.Axis(),Center);
1653 Standard_Real Rad = Cy.Radius()+Z*Tan(alpha);
1654 if (Rad < 0.) {
1655 Rad = -Rad;
1656 }
1657 else {
1658 alpha = -alpha;
1659 }
1660 gp_Cone co(axcone,alpha,Rad);
1661 NewS = new Geom_ConicalSurface(co);
1662 }
1663 else {
1664 NewS = S;
1665 }
1666 }
1667 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1668
1669 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1670 if (Abs(testdir) <= 1.-Precision::Angular()) {
1671#ifdef DEB
1672 cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << endl;
1673#endif
1674 return NewS;
1675 }
1676
1677 gp_Cone Co1 = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1678
1679 testdir = Direction.Dot(Co1.Axis().Direction());
1680 if (Abs(testdir) <= 1.-Precision::Angular()) {
1681#ifdef DEB
1682 cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << endl;
1683#endif
1684 return NewS;
1685 }
1686
1687
1688 IntAna_QuadQuadGeo i2s;
1689 i2s.Perform(NeutralPlane,Co1,Precision::Angular(),Precision::Confusion());
1690 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1691#ifdef DEB
1692 cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << endl;
1693#endif
1694 return NewS;
1695 }
1696 gp_Ax3 axcone = Co1.Position();
0d969553 1697 // Pb : Where is the material???
7fd59977 1698 Standard_Real alpha = Angle;
1699 Standard_Boolean direct(axcone.Direct());
1700 if ((direct && Oris == TopAbs_REVERSED) ||
1701 (!direct && Oris == TopAbs_FORWARD)) {
1702 alpha = -alpha;
1703 }
1704
1705 gp_Pnt Center = i2s.Circle(1).Location();
1706 if (Abs(Angle) > Precision::Angular()) {
1707 if (testdir <0.) {
1708 alpha = -alpha;
1709 }
1710 Standard_Real Z = ElCLib::LineParameter(Co1.Axis(),Center);
1711 Standard_Real Rad = i2s.Circle(1).Radius()+Z*Tan(alpha);
1712 if (Rad < 0.) {
1713 Rad = -Rad;
1714 }
1715 else {
1716 alpha = -alpha;
1717 }
1718 if (Abs(alpha-Co1.SemiAngle()) < Precision::Angular()) {
1719 NewS = S;
1720 }
1721 else {
1722 gp_Cone co(axcone,alpha,Rad);
1723 NewS = new Geom_ConicalSurface(co);
1724 }
1725 }
1726 else {
1727 NewS = new
1728 Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
1729 }
1730 }
1731 else {
1732#ifdef DEB
1733 cout << "NewSurface:Draft_SurfNotYetImplemented" << endl;
1734#endif
1735 }
1736 return NewS;
1737}
1738
1739
1740//=======================================================================
1741//function : NewCurve
1742//purpose :
1743//=======================================================================
1744
1745Handle(Geom_Curve) Draft_Modification::NewCurve
1746 (const Handle(Geom_Curve)& C,
1747 const Handle(Geom_Surface)& S,
1748 const TopAbs_Orientation Oris,
1749 const gp_Dir& Direction,
1750 const Standard_Real Angle,
1751 const gp_Pln& NeutralPlane,
1752 const Standard_Boolean )
1753
1754{
1755 Handle(Geom_Curve) NewC;
1756
1757 Handle(Standard_Type) TypeS = S->DynamicType();
1758
1759 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1760 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1761 gp_Ax1 Axe;
1762 Standard_Real Theta;
1763 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1764 if ( Abs(Theta) > Precision::Angular()) {
1765 NewC = Handle(Geom_Curve)::DownCast(C->Rotated(Axe,Theta));
1766 }
1767 else {
1768 NewC = C;
1769 }
1770 }
1771 return NewC;
1772 }
1773
1774
1775 if (C->DynamicType() != STANDARD_TYPE(Geom_Line)) {
1776 return NewC;
1777 }
1778
1779
1780 gp_Lin lin = Handle(Geom_Line)::DownCast(C)->Lin();
1781// Standard_Real testdir = Direction.Dot(lin.Direction());
1782// if (Abs(testdir) <= 1.-Precision::Angular()) {
1783// return NewC;
1784// }
1785 gp_Dir Norm;
1786 if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1787 Standard_Real U,V;
1788 gp_Vec d1u,d1v;
1789 gp_Pnt pbid;
1790 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1791 ElSLib::Parameters(Cy,lin.Location(),U,V);
1792 ElSLib::D1(U,V,Cy,pbid,d1u,d1v);
1793 Norm = d1u.Crossed(d1v);
1794 }
1795 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1796 Standard_Real U,V;
1797 gp_Vec d1u,d1v;
1798 gp_Pnt pbid;
1799 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1800 ElSLib::Parameters(Co,lin.Location(),U,V);
1801 ElSLib::D1(U,V,Co,pbid,d1u,d1v);
1802 Norm = d1u.Crossed(d1v);
1803 }
1804
1805 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
1806 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
1807 if (Oris == TopAbs_REVERSED) {
1808 Norm.Reverse();
1809 }
1810 gp_Ax1 axrot(ilipl.Point(1), Norm.Crossed(Direction));
1811 gp_Lin lires = gp_Lin(gp_Ax1(ilipl.Point(1),Direction)).
1812 Rotated(axrot,Angle);
1813 if (lires.Direction().Dot(lin.Direction()) < 0.) {
1814 lires.Reverse();
1815 }
1816 NewC = new Geom_Line(lires);
1817 }
1818 return NewC;
1819}
1820
1821
1822//=======================================================================
1823//function : Choose
1824//purpose :
1825//=======================================================================
1826
1827static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
1828 Draft_DataMapOfEdgeEdgeInfo& theEMap,
1829 const TopoDS_Vertex& Vtx,
1830 Draft_VertexInfo& Vinf,
1831 GeomAdaptor_Curve& AC,
1832 GeomAdaptor_Surface& AS)
1833{
1834 gp_Vec tgref;
1835 Vinf.InitEdgeIterator();
1836
0d969553 1837 // Find a regular edge with null SecondFace
7fd59977 1838 while (Vinf.MoreEdge()) {
1839 const TopoDS_Edge& E1 = Vinf.Edge();
1840 const Draft_EdgeInfo& Einf1 = theEMap(E1);
1841 if (Einf1.SecondFace().IsNull()) {
1842 break;
1843 }
1844 else {
1845 GeomAbs_Shape te = BRep_Tool::Continuity(E1,Einf1.FirstFace(),
1846 Einf1.SecondFace());
1847 if (te >= GeomAbs_G1) {
1848 break;
1849 }
1850 }
1851 Vinf.NextEdge();
1852 }
0d969553 1853 if (!Vinf.MoreEdge()) { // take the first edge
7fd59977 1854 Vinf.InitEdgeIterator();
1855 }
1856
1857 const TopoDS_Edge& Eref = Vinf.Edge();
1858 //const Draft_EdgeInfo& Einf = theEMap(Eref);
1859 Draft_EdgeInfo& Einf = theEMap(Eref);
1860
1861 AC.Load(Einf.Geometry());
1862
1863 Standard_Real f,l,prm;
1864 TopLoc_Location Loc;
1865 Handle(Geom_Curve) C = BRep_Tool::Curve(Eref,Loc,f,l);
1866 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1867 gp_Pnt ptbid;
1868 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1869 Standard_Integer done;
1870 Standard_Real param = Parameter( C, BRep_Tool::Pnt(Vtx), done );
1871 if (done != 0)
1872 {
1873 Handle( Geom_Surface ) S1 = theFMap(Einf.FirstFace()).Geometry();
1874 Handle( Geom_Surface ) S2 = theFMap(Einf.SecondFace()).Geometry();
1875 prm = SmartParameter( Einf, BRep_Tool::Tolerance(Eref), BRep_Tool::Pnt(Vtx), done, S1, S2 );
1876 }
1877 else
1878 prm = param;
1879 C->D1(prm,ptbid,tgref);
1880
1881
1882 Vinf.InitEdgeIterator();
1883 while (Vinf.MoreEdge()) {
0d969553 1884 // Find a non tangent edge
7fd59977 1885 const TopoDS_Edge& Edg = Vinf.Edge();
1886 if (!Edg.IsSame(Eref)) {
1887 //const Draft_EdgeInfo& Einfo = theEMap(Edg);
1888 Draft_EdgeInfo& Einfo = theEMap(Edg);
1889 if (!Einfo.SecondFace().IsNull() &&
1890 BRep_Tool::Continuity(Edg,Einfo.FirstFace(),Einfo.SecondFace())
1891 <= GeomAbs_C0) {
1892 C = BRep_Tool::Curve(Edg,Loc,f,l);
1893 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1894 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1895 Standard_Integer anewdone;
1896 Standard_Real anewparam = Parameter( C, BRep_Tool::Pnt(Vtx), anewdone );
1897 if (anewdone != 0)
1898 {
1899 Handle( Geom_Surface ) S1 = theFMap(Einfo.FirstFace()).Geometry();
1900 Handle( Geom_Surface ) S2 = theFMap(Einfo.SecondFace()).Geometry();
1901 prm = SmartParameter( Einfo, BRep_Tool::Tolerance(Edg), BRep_Tool::Pnt(Vtx), anewdone, S1, S2 );
1902 }
1903 else
1904 prm = anewparam;
1905 gp_Vec tg;
1906 C->D1(prm,ptbid,tg);
1907 if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
1908 break;
1909 }
1910 }
1911 }
1912 Vinf.NextEdge();
1913 }
1914 if (!Vinf.MoreEdge()) {
1915 return Standard_False;
1916 }
1917
1918 const Draft_EdgeInfo& Einf2 = theEMap(Vinf.Edge());
1919 if (!Einf.SecondFace().IsNull()) {
1920
1921 if (Einf2.FirstFace().IsSame(Einf.FirstFace()) ||
1922 Einf2.FirstFace().IsSame(Einf.SecondFace())) {
1923 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1924 }
1925 else {
1926 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1927 }
1928 }
1929 else {
1930 if (Einf2.FirstFace().IsSame(Einf.FirstFace())) {
1931 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1932 }
1933 else {
1934 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1935 }
1936 }
1937 return Standard_True;
1938}
1939
1940
1941//=======================================================================
1942//function : Parameter
1943//purpose :
1944//=======================================================================
1945
1946static Standard_Real Parameter(const Handle(Geom_Curve)& C,
1947 const gp_Pnt& P,
1948 Standard_Integer& done)
1949{
1950 done = 0;
1951 Handle(Geom_Curve) cbase = C;
1952 Handle(Standard_Type) ctyp = C->DynamicType();
1953 if (ctyp == STANDARD_TYPE(Geom_TrimmedCurve)) {
1954 cbase = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
1955 ctyp = cbase->DynamicType();
1956 }
1957 Standard_Real param;
1958 if (ctyp == STANDARD_TYPE(Geom_Line)) {
1959 param = ElCLib::Parameter(Handle(Geom_Line)::DownCast(cbase)->Lin(),P);
1960 }
1961 else if (ctyp == STANDARD_TYPE(Geom_Circle)) {
1962 param = ElCLib::Parameter(Handle(Geom_Circle)::DownCast(cbase)->Circ(),P);
c6541a0c 1963 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
7fd59977 1964 param = 0.;
1965 }
1966 }
1967 else if (ctyp == STANDARD_TYPE(Geom_Ellipse)) {
1968 param = ElCLib::Parameter(Handle(Geom_Ellipse)::DownCast(cbase)->Elips(),P);
c6541a0c 1969 if (Abs(2.*M_PI-param) <=Epsilon(2.*M_PI)) {
7fd59977 1970 param = 0.;
1971 }
1972 }
1973 else if (ctyp == STANDARD_TYPE(Geom_Parabola)) {
1974 param = ElCLib::Parameter(Handle(Geom_Parabola)::DownCast(cbase)->Parab(),P);
1975 }
1976 else if (ctyp == STANDARD_TYPE(Geom_Hyperbola)) {
1977 param = ElCLib::Parameter(Handle(Geom_Hyperbola)::DownCast(cbase)->Hypr(),P);
1978 }
1979 else {
1980 GeomAdaptor_Curve TheCurve(C);
1981 Extrema_ExtPC myExtPC(P,TheCurve);
1982 if (!myExtPC.IsDone()) {
1983 Standard_Failure::Raise();
1984 }
1985 if (myExtPC.NbExt() >= 1) {
1986 Standard_Real Dist2, Dist2Min = myExtPC.SquareDistance(1);
1987 Standard_Integer j, jmin = 1;
1988 for (j = 2; j <= myExtPC.NbExt(); j++) {
1989 Dist2 = myExtPC.SquareDistance(j);
1990 if (Dist2 < Dist2Min) {
1991 Dist2Min = Dist2;
1992 jmin = j;
1993 }
1994 }
1995 param = myExtPC.Point(jmin).Parameter();
1996 }
1997 else {
1998 Standard_Real dist1_2,dist2_2;
1999 gp_Pnt p1b,p2b;
2000 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
2001 if (dist1_2 < dist2_2) {
2002 done = -1;
2003 param = TheCurve.FirstParameter();
2004 }
2005 else {
2006 done = 1;
2007 param = TheCurve.LastParameter();
2008 }
2009 }
2010
2011 if (cbase->IsPeriodic()) {
2012 Standard_Real Per = cbase->Period();
2013 Standard_Real Tolp = Precision::Parametric(Precision::Confusion());
2014 if (Abs(Per-param) <= Tolp) {
2015 param = 0.;
2016 }
2017 }
2018 }
2019 return param;
2020}
2021
2022//=======================================================================
2023//function : SmartParameter
2024//purpose :
2025//=======================================================================
2026
2027static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
2028 const Standard_Real EdgeTol,
2029 const gp_Pnt& Pnt,
2030 const Standard_Integer sign,
2031 const Handle(Geom_Surface)& S1,
2032 const Handle(Geom_Surface)& S2)
2033{
2034 Handle( Geom2d_Curve ) NewC2d;
2035 Standard_Real Tol = Precision::Confusion();
2036 Standard_Real Etol = EdgeTol;
2037
2038 Handle( Geom2d_Curve ) pcu1 = Einf.FirstPC();
2039 Handle( Geom2d_Curve ) pcu2 = Einf.SecondPC();
2040
2041 if (pcu1.IsNull())
2042 {
2043 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2044 pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
2045 Einf.ChangeFirstPC() = pcu1;
2046 }
2047 if (pcu2.IsNull())
2048 {
2049 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2050 pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
2051 Einf.ChangeSecondPC() = pcu2;
2052 }
2053
2054 GeomAPI_ProjectPointOnSurf Projector( Pnt, S1 );
2055 Standard_Real U, V;
2056 Projector.LowerDistanceParameters( U, V );
2057
2058 NewC2d = Einf.FirstPC();
2059 if (NewC2d->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
2060 NewC2d = (Handle(Geom2d_TrimmedCurve)::DownCast(NewC2d))->BasisCurve();
2061
2062 gp_Pnt2d P2d( U, V );
2063 Geom2dAPI_ProjectPointOnCurve Projector2d( P2d, NewC2d );
2064 if (Projector2d.NbPoints() == 0 || Projector2d.LowerDistance() > Tol)
2065 {
2066 Handle( Geom2d_BSplineCurve ) BCurve;
2067 if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
2068 BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
2069 else
2070 BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
2071 if (sign == -1)
2072 {
2073 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2074 PntArray(1) = P2d;
2075 PntArray(2) = BCurve->Pole(1);
2076 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2077 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2078 Concat.Add( Patch, Tol, Standard_False );
2079 BCurve = Concat.BSplineCurve();
2080 }
2081 else
2082 {
2083 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2084 PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
2085 PntArray(2) = P2d;
2086 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2087 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2088 Concat.Add( Patch, Tol, Standard_True );
2089 BCurve = Concat.BSplineCurve();
2090 }
2091 NewC2d = BCurve;
2092 }
2093 Einf.ChangeFirstPC() = NewC2d;
2094 Handle( Geom2dAdaptor_HCurve ) hcur = new Geom2dAdaptor_HCurve( NewC2d );
2095 Handle( GeomAdaptor_HSurface ) hsur = new GeomAdaptor_HSurface( S1 );
2096 Adaptor3d_CurveOnSurface cons( hcur, hsur );
2097 Handle( Adaptor3d_HCurveOnSurface ) hcons = new Adaptor3d_HCurveOnSurface( cons );
2098 Handle( GeomAdaptor_HSurface ) hsur2 = new GeomAdaptor_HSurface( S2 );
2099 ProjLib_CompProjectedCurve ProjCurve( hsur2, hcons, Tol, Tol );
2100 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
2101 HProjector->Set( ProjCurve );
2102 Standard_Real Udeb, Ufin;
2103 ProjCurve.Bounds(1, Udeb, Ufin);
2104 Standard_Integer MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
2105 Approx_CurveOnSurface appr( HProjector, hsur2, Udeb, Ufin, Tol,
2106 GeomAbs_C1, 10, MaxSeg,
2107 Standard_False, Standard_False );
2108 Einf.ChangeSecondPC() = appr.Curve2d();
2109 Einf.ChangeGeometry() = appr.Curve3d();
2110 Einf.SetNewGeometry( Standard_True );
2111
2112 if (sign == -1)
2113 return Einf.Geometry()->FirstParameter();
2114 else
2115 return Einf.Geometry()->LastParameter();
2116
2117}
2118
2119//=======================================================================
2120//function : Orientation
2121//purpose :
2122//=======================================================================
2123
2124static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
2125 const TopoDS_Face& F)
2126{
2127//
0d969553 2128// change porting NT
7fd59977 2129//
2130 TopExp_Explorer expl ;
2131 expl.Init(S,
2132 TopAbs_FACE) ;
2133 while (expl.More()) {
2134 if (TopoDS::Face(expl.Current()).IsSame(F)) {
2135 return expl.Current().Orientation();
2136 }
2137 expl.Next();
2138 }
2139 return TopAbs_FORWARD;
2140}
2141
2142
2143//=======================================================================
2144//function : FindRotation
2145//purpose :
2146//=======================================================================
2147
2148static Standard_Boolean FindRotation(const gp_Pln& Pl,
2149 const TopAbs_Orientation Oris,
2150 const gp_Dir& Direction,
2151 const Standard_Real Angle,
2152 const gp_Pln& NeutralPlane,
2153 gp_Ax1& Axe,
2154 Standard_Real& theta)
2155{
2156 IntAna_QuadQuadGeo i2pl(Pl,NeutralPlane,
2157 Precision::Angular(),Precision::Confusion());
2158
2159 if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
2160 gp_Lin li = i2pl.Line(1);
0d969553 2161 // Try to turn around this line
7fd59977 2162 gp_Dir nx = li.Direction();
2163 gp_Dir ny = Pl.Axis().Direction().Crossed(nx);
2164 Standard_Real a = Direction.Dot(nx);
2165 if (Abs(a) <=1-Precision::Angular()) {
2166 Standard_Real b = Direction.Dot(ny);
2167 Standard_Real c = Direction.Dot(Pl.Axis().Direction());
2168 Standard_Boolean direct(Pl.Position().Direct());
2169 if ((direct && Oris == TopAbs_REVERSED) ||
2170 (!direct && Oris == TopAbs_FORWARD)) {
2171 b = -b;
2172 c = -c;
2173 }
2174 Standard_Real denom = Sqrt(1-a*a);
2175 Standard_Real Sina = Sin(Angle);
2176 if (denom>Abs(Sina)) {
2177 Standard_Real phi = ATan2(b/denom,c/denom);
2178 Standard_Real theta0 = ACos(Sina/denom);
2179 theta = theta0 - phi;
2180 if (Cos(theta) <0.) {
2181 theta = -theta0 -phi;
2182 }
2183 // modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
c6541a0c
D
2184 while (Abs(theta)>M_PI) {
2185 theta = theta + M_PI*(theta<0 ? 1 : -1);
7fd59977 2186 }
2187 // modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
2188 Axe = li.Position();
2189 return Standard_True;
2190 }
2191 }
2192 }
2193 return Standard_False;
2194}
2195