Commit | Line | Data |
---|---|---|
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 | ||
121 | static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo&, | |
122 | Draft_DataMapOfEdgeEdgeInfo&, | |
123 | const TopoDS_Vertex&, | |
124 | Draft_VertexInfo&, | |
125 | GeomAdaptor_Curve&, | |
126 | GeomAdaptor_Surface&); | |
127 | ||
128 | static Standard_Real Parameter(const Handle(Geom_Curve)&, | |
129 | const gp_Pnt&, | |
130 | Standard_Integer&); | |
131 | ||
132 | static 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 | ||
139 | static TopAbs_Orientation Orientation(const TopoDS_Shape&, | |
140 | const TopoDS_Face&); | |
141 | ||
142 | static 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 | ||
156 | Standard_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 | ||
422 | Standard_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 | ||
693 | void 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 | ||
1590 | Handle(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 | ||
1745 | Handle(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 | ||
1827 | static 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 | ||
1946 | static 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 | ||
2027 | static 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 | ||
2124 | static 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 | ||
2148 | static 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 |