b311480e |
1 | // Created on: 1999-04-15 |
2 | // Created by: Roman LYGIN |
3 | // Copyright (c) 1999-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
7fd59977 |
17 | // gka 23.06.99 S4208: using tool SU_TransferParameter |
18 | // pdn 13.07.99 synchronizing splitting values on 3d curve and pcurve |
19 | // abv 14.07.99 dealing with edges without 3d curve |
20 | // svv 10.01.00 porting on DEC |
21 | |
22 | #include <ShapeUpgrade_WireDivide.ixx> |
23 | #include <ShapeUpgrade.hxx> |
24 | #include <BRep_Tool.hxx> |
25 | #include <BRep_Builder.hxx> |
26 | #include <BRepLib_MakeFace.hxx> |
27 | #include <BRepLib_MakeWire.hxx> |
28 | #include <TopoDS.hxx> |
29 | #include <TopoDS_Vertex.hxx> |
30 | #include <TopoDS_Edge.hxx> |
31 | #include <TopoDS_Iterator.hxx> |
32 | #include <ShapeBuild_Edge.hxx> |
33 | #include <ShapeAnalysis_Edge.hxx> |
34 | #include <Precision.hxx> |
35 | #include <TopExp.hxx> |
36 | #include <TopExp_Explorer.hxx> |
37 | #include <TColStd_HSequenceOfReal.hxx> |
38 | #include <TColGeom_HArray1OfCurve.hxx> |
39 | #include <TColGeom2d_HArray1OfCurve.hxx> |
40 | #include <gp_Pnt.hxx> |
41 | #include <Geom_Curve.hxx> |
42 | #include <Geom2d_Curve.hxx> |
43 | #include <ShapeExtend.hxx> |
44 | #include <TColStd_Array1OfBoolean.hxx> |
45 | #include <ShapeBuild_ReShape.hxx> |
46 | #include <ShapeAnalysis_TransferParametersProj.hxx> |
47 | #include <ShapeUpgrade_FixSmallCurves.hxx> |
48 | #include <TopTools_SequenceOfShape.hxx> |
49 | #include <TColStd_SequenceOfReal.hxx> |
50 | #include <GeomAdaptor_HSurface.hxx> |
51 | #include <Geom2dAdaptor_HCurve.hxx> |
52 | #include <ShapeAnalysis_Curve.hxx> |
53 | #include <Adaptor3d_CurveOnSurface.hxx> |
ec357c5c |
54 | #include <Geom_BoundedCurve.hxx> |
55 | #include <Geom2d_BoundedCurve.hxx> |
7fd59977 |
56 | |
57 | //======================================================================= |
58 | //function : ShapeUpgrade_WireDivide |
59 | //purpose : |
60 | //======================================================================= |
61 | |
62 | ShapeUpgrade_WireDivide::ShapeUpgrade_WireDivide(): |
63 | ShapeUpgrade_Tool(), myStatus(0) |
64 | { |
65 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide"<<endl; |
66 | mySplitCurve3dTool = new ShapeUpgrade_SplitCurve3d; |
67 | mySplitCurve2dTool = new ShapeUpgrade_SplitCurve2d; |
68 | myTransferParamTool = new ShapeAnalysis_TransferParametersProj; |
69 | myEdgeMode = 2; |
70 | myFixSmallCurveTool = new ShapeUpgrade_FixSmallCurves; |
71 | myEdgeDivide = new ShapeUpgrade_EdgeDivide; |
72 | } |
73 | |
74 | //======================================================================= |
75 | //function : Init |
76 | //purpose : |
77 | //======================================================================= |
78 | |
79 | void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W, |
80 | const TopoDS_Face& F) |
81 | { |
82 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Face"<<endl; |
83 | myWire = W; |
84 | myFace = F; |
85 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
86 | } |
87 | |
88 | //======================================================================= |
89 | //function : Init |
90 | //purpose : |
91 | //======================================================================= |
92 | |
93 | void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W, |
94 | const Handle(Geom_Surface)& S) |
95 | { |
96 | // if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Surface "<<endl; |
97 | myWire = W; |
1c72dff6 |
98 | BRepLib_MakeFace mkf(S, Precision::Confusion()); |
7fd59977 |
99 | myFace = mkf.Face(); |
100 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
101 | } |
102 | |
103 | //======================================================================= |
104 | //function : Load |
105 | //purpose : |
106 | //======================================================================= |
107 | |
108 | void ShapeUpgrade_WireDivide::Load(const TopoDS_Wire& W) |
109 | { |
110 | myWire = W; |
111 | } |
112 | |
113 | //======================================================================= |
114 | //function : Load |
115 | //purpose : |
116 | //======================================================================= |
117 | |
118 | void ShapeUpgrade_WireDivide::Load(const TopoDS_Edge& E) |
119 | { |
120 | BRepLib_MakeWire MakeWire (E); |
121 | if (MakeWire.IsDone()) |
122 | Load (MakeWire.Wire()); |
123 | } |
124 | |
125 | //======================================================================= |
126 | //function : SetFace |
127 | //purpose : |
128 | //======================================================================= |
129 | |
130 | void ShapeUpgrade_WireDivide::SetFace(const TopoDS_Face& F) |
131 | { |
132 | myFace = F; |
133 | } |
134 | |
135 | //======================================================================= |
136 | //function : SetSurface |
137 | //purpose : |
138 | //======================================================================= |
139 | |
140 | void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S) |
141 | { |
1c72dff6 |
142 | BRepLib_MakeFace mkf(S, Precision::Confusion()); |
7fd59977 |
143 | myFace = mkf.Face(); |
144 | } |
145 | |
146 | //======================================================================= |
147 | //function : SetSurface |
148 | //purpose : |
149 | //======================================================================= |
150 | |
151 | void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S, |
152 | const TopLoc_Location& L) |
153 | { |
154 | BRep_Builder B; |
155 | B.MakeFace(myFace,S,L,Precision::Confusion()); |
156 | } |
157 | |
158 | //======================================================================= |
159 | //function : Perform |
160 | //purpose : |
161 | //======================================================================= |
162 | |
163 | static void CorrectSplitValues(const Handle(TColStd_HSequenceOfReal) orig3d, |
164 | const Handle(TColStd_HSequenceOfReal) orig2d, |
165 | Handle(TColStd_HSequenceOfReal) new2d, |
166 | Handle(TColStd_HSequenceOfReal) new3d) |
167 | { |
168 | Standard_Real preci = Precision::PConfusion(); |
169 | Standard_Integer len3d = orig3d->Length(); |
170 | Standard_Integer len2d = orig2d->Length(); |
171 | TColStd_Array1OfBoolean fixNew2d (1, len3d); |
172 | fixNew2d.Init (Standard_False); |
173 | TColStd_Array1OfBoolean fixNew3d (1, len2d); |
174 | fixNew3d.Init (Standard_False); |
175 | Standard_Real Last3d = orig3d->Value(len3d); |
176 | Standard_Real Last2d = orig2d->Value(len2d); |
177 | |
178 | Standard_Integer i;// svv #1 |
179 | for( i = 1; i <= len3d ; i++) { |
180 | Standard_Real par = new2d->Value(i); |
181 | Standard_Integer index = 0; |
182 | for(Standard_Integer j = 1; j <= len2d && !index; j++) |
183 | if(Abs(par-orig2d->Value(j)) < preci) |
184 | index = j; |
185 | if(index&&!fixNew3d(index)) { |
186 | Standard_Real newPar = orig2d->Value(index); |
187 | new2d->SetValue(i,newPar); |
188 | fixNew2d(i) = Standard_True; |
189 | Standard_Real newPar3d = orig3d->Value(i); |
190 | new3d->SetValue(index,newPar3d); |
191 | fixNew3d(index) = Standard_True; |
192 | } |
193 | } |
194 | |
195 | for(i = 1; i <= len2d ; i++) { |
196 | Standard_Real par = new3d->Value(i); |
197 | Standard_Integer index = 0; |
198 | for(Standard_Integer j = 1; j <= len3d && !index; j++) |
199 | if(Abs(par-orig3d->Value(j)) < preci) |
200 | index = j; |
201 | if(index&&!fixNew2d(index)) { |
202 | Standard_Real newPar = orig3d->Value(index); |
203 | new3d->SetValue(i,newPar); |
204 | fixNew3d(i) = Standard_True; |
205 | Standard_Real newPar2d = orig2d->Value(i); |
206 | new2d->SetValue(index,newPar2d); |
207 | fixNew2d(index) = Standard_True; |
208 | } |
209 | } |
210 | |
211 | Standard_Real dpreci = 2* preci; |
212 | for(i = 1; i < len3d; i++) { |
213 | Standard_Real dist = new2d->Value(i+1) - new2d->Value(i); |
214 | if(dist < preci) { |
215 | if(fixNew2d(i+1)) { |
216 | //changing |
217 | Standard_Real tmp = new2d->Value(i+1); |
218 | new2d->SetValue(i+1,new2d->Value(i)+dpreci); |
219 | new2d->SetValue(i,tmp); |
220 | fixNew2d(i) = Standard_True; |
221 | fixNew2d(i+1) = Standard_False; |
222 | } |
223 | else |
224 | new2d->SetValue(i+1,new2d->Value(i)+dpreci); |
225 | } |
226 | } |
227 | if(new2d->Value(len3d) > Last3d) { |
228 | Standard_Integer ind; // svv #1 |
229 | for( ind = len3d; ind > 1 && !fixNew2d(ind); ind--); |
230 | Standard_Real lastFix = new2d->Value(ind); |
231 | for(i = len3d; i >= ind; i--) { |
232 | new2d->SetValue(i,lastFix); |
233 | lastFix-=dpreci; |
234 | } |
235 | } |
236 | |
237 | for(i = 1; i < len2d; i++) { |
238 | Standard_Real dist = new3d->Value(i+1) - new3d->Value(i); |
239 | if(dist < preci) { |
240 | if(fixNew3d(i+1)) { |
241 | //changing |
242 | Standard_Real tmp = new3d->Value(i+1); |
243 | new3d->SetValue(i+1,new3d->Value(i)+dpreci); |
244 | new3d->SetValue(i,tmp); |
245 | fixNew3d(i) = Standard_True; |
246 | fixNew3d(i+1) = Standard_False; |
247 | } |
248 | else |
249 | new3d->SetValue(i+1,new3d->Value(i)+dpreci); |
250 | } |
251 | } |
252 | if(new3d->Value(len2d) > Last2d) { |
253 | Standard_Integer ind; // svv #1 |
254 | for(ind = len2d; ind > 1 && !fixNew3d(ind); ind--); |
255 | Standard_Real lastFix = new3d->Value(ind); |
256 | for(i = len2d; i >= ind; i--) { |
257 | new3d->SetValue(i,lastFix); |
258 | lastFix-=dpreci; |
259 | } |
260 | } |
261 | } |
262 | |
263 | void ShapeUpgrade_WireDivide::Perform () |
264 | { |
265 | |
266 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
267 | |
268 | // if (ShapeUpgrade::Debug()) cout << "ShapeUpgrade_WireDivide::Perform" << endl; |
269 | |
270 | BRep_Builder B; |
271 | ShapeAnalysis_Edge sae; |
272 | |
273 | TopoDS_Wire newWire; |
274 | B.MakeWire (newWire); |
275 | TopLoc_Location Loc; |
276 | Handle(Geom_Surface) Surf; |
277 | if(!myFace.IsNull()) |
278 | Surf = BRep_Tool::Surface(myFace, Loc); |
279 | |
280 | Standard_Boolean isSplit3d = Standard_True; |
281 | switch(myEdgeMode) { |
282 | case 0: if(!myFace.IsNull()) isSplit3d = Standard_False; break; |
283 | case 1: if(myFace.IsNull()) isSplit3d = Standard_False; break; |
284 | default : break; |
285 | } |
286 | myEdgeDivide->SetFace(myFace); |
287 | if(isSplit3d) |
288 | myEdgeDivide->SetSplitCurve3dTool(GetSplitCurve3dTool()); |
289 | myEdgeDivide->SetSplitCurve2dTool(GetSplitCurve2dTool()); |
290 | for (TopoDS_Iterator ItW (myWire,Standard_False); ItW.More(); ItW.Next()) { |
291 | // for each Edge: |
292 | TopoDS_Shape sh = Context()->Apply(ItW.Value(),TopAbs_SHAPE); |
293 | for(TopExp_Explorer exp(sh,TopAbs_EDGE); exp.More(); exp.Next()) { |
294 | TopoDS_Edge E = TopoDS::Edge(exp.Current()); |
295 | // if (ShapeUpgrade::Debug()) cout << ".. Edge " << (void*) &(*E.TShape()) << endl; |
296 | |
297 | // skip degenerated edges (and also INTERNAL/EXTERNAL, to avoid failures) |
298 | if ( E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL ) { |
299 | B.Add ( newWire, E ); |
300 | continue; |
301 | } |
302 | |
303 | if(!myEdgeDivide->Compute(E)) { |
304 | B.Add ( newWire, E ); |
305 | continue; |
306 | } |
307 | // first iteration: getting split knots |
308 | // on 3D curve: preliminary |
309 | |
310 | Handle(ShapeAnalysis_TransferParameters) theTransferParamTool = GetTransferParamTool(); |
311 | theTransferParamTool->SetMaxTolerance(MaxTolerance()); |
312 | theTransferParamTool->Init(E,myFace); |
313 | Standard_Boolean wasSR = theTransferParamTool->IsSameRange(); |
314 | |
315 | // on pcurve(s): all knots |
316 | // assume that if seam-edge, its pcurve1 and pcurve2 has the same split knots !!! |
317 | Handle(TColStd_HSequenceOfReal) theKnots3d = myEdgeDivide->Knots3d(); |
318 | Handle(TColStd_HSequenceOfReal) theKnots2d = myEdgeDivide->Knots2d(); |
319 | |
320 | // second iteration: transfer parameters and build segments |
321 | Handle(TColStd_HSequenceOfReal) SplitValues2d; |
322 | Handle(TColStd_HSequenceOfReal) SplitValues3d; |
323 | if(myEdgeDivide->HasCurve2d() && myEdgeDivide->HasCurve3d() ) { |
324 | SplitValues2d = theTransferParamTool->Perform(theKnots3d,Standard_True); |
325 | SplitValues3d = theTransferParamTool->Perform(theKnots2d,Standard_False); |
326 | CorrectSplitValues(theKnots3d,theKnots2d,SplitValues2d,SplitValues3d); |
327 | } |
328 | Handle(ShapeUpgrade_SplitCurve3d) theSplit3dTool = myEdgeDivide->GetSplitCurve3dTool(); |
329 | Handle(ShapeUpgrade_SplitCurve2d) theSplit2dTool = myEdgeDivide->GetSplitCurve2dTool(); |
330 | |
331 | if ( myEdgeDivide->HasCurve2d() ) { |
332 | if(! theKnots3d.IsNull() ) { |
333 | SplitValues2d->Remove(1); |
334 | SplitValues2d->Remove(SplitValues2d->Length()); |
335 | theSplit2dTool->SetSplitValues (SplitValues2d); |
336 | } |
337 | theSplit2dTool->Build(Standard_True); |
338 | } |
339 | if ( myEdgeDivide->HasCurve3d() ) { |
340 | if( ! theKnots2d.IsNull() ) { |
341 | SplitValues3d->Remove(1); |
342 | SplitValues3d->Remove(SplitValues3d->Length()); |
343 | theSplit3dTool->SetSplitValues (SplitValues3d); |
344 | } |
345 | theSplit3dTool->Build (Standard_True); |
346 | } |
347 | // get 2d and 3d split values which should be the same |
348 | if ( myEdgeDivide->HasCurve2d() ) theKnots2d = theSplit2dTool->SplitValues(); |
349 | if ( myEdgeDivide->HasCurve3d() ) theKnots3d = theSplit3dTool->SplitValues(); |
350 | |
351 | Standard_Boolean isSeam = Standard_False; |
352 | if (! myFace.IsNull() ) |
353 | isSeam = BRep_Tool::IsClosed ( E, myFace ); |
354 | Handle(TColGeom2d_HArray1OfCurve) theSegments2d; |
355 | if(myEdgeDivide->HasCurve2d()) |
356 | theSegments2d = theSplit2dTool->GetCurves(); |
357 | Handle(TColGeom2d_HArray1OfCurve) theSegments2dR; |
358 | if ( isSeam ) { |
359 | Handle(Geom2d_Curve) c2; |
360 | Standard_Real f2, l2; |
361 | //smh#8 |
362 | TopoDS_Shape tmpE = E.Reversed(); |
363 | TopoDS_Edge erev = TopoDS::Edge (tmpE ); |
364 | if ( sae.PCurve ( erev, myFace, c2, f2, l2, Standard_False) ) { |
365 | theSplit2dTool->Init (c2, f2, l2); |
366 | if(!theKnots2d.IsNull()) |
367 | theSplit2dTool->SetSplitValues (theKnots2d); |
368 | theSplit2dTool->Perform (Standard_True); |
369 | Handle(TColStd_HSequenceOfReal) revKnots2d = theSplit2dTool->SplitValues(); |
dede2e21 |
370 | if(revKnots2d->Length()!=theKnots2d->Length()) { |
7fd59977 |
371 | isSeam = Standard_False; |
0797d9d3 |
372 | #ifdef OCCT_DEBUG |
7fd59977 |
373 | cout << "Error: ShapeUpgrade_WireDivide: seam has different splitting values on pcurvesd" << endl; |
374 | #endif |
375 | } |
376 | else |
377 | theSegments2dR = theSplit2dTool->GetCurves(); |
378 | } |
379 | else isSeam = Standard_False; |
380 | } |
381 | |
382 | // Exploring theEdge |
383 | TopoDS_Vertex V1o = TopExp::FirstVertex (E, Standard_False); |
384 | TopoDS_Vertex V2o = TopExp::LastVertex (E, Standard_False); |
385 | Standard_Boolean isForward = ( E.Orientation() == TopAbs_FORWARD ); |
386 | Standard_Real TolEdge = BRep_Tool::Tolerance (E); |
387 | Standard_Boolean isDeg = BRep_Tool::Degenerated ( E ); |
388 | |
389 | // Copy vertices to protect original shape against SameParamseter |
390 | //smh#8 |
391 | TopoDS_Shape emptyCopiedV1 = V1o.EmptyCopied(); |
392 | TopoDS_Vertex V1 = TopoDS::Vertex ( emptyCopiedV1 ); |
393 | Context()->Replace ( V1o, V1 ); |
394 | TopoDS_Vertex V2; |
395 | if ( V1o.IsSame ( V2o ) ) { |
396 | //smh#8 |
397 | TopoDS_Shape tmpV = V1.Oriented(V2o.Orientation() ); |
398 | V2 = TopoDS::Vertex ( tmpV ); |
399 | } |
400 | else { |
401 | //smh#8 |
402 | TopoDS_Shape emptyCopied = V2o.EmptyCopied(); |
403 | V2 = TopoDS::Vertex ( emptyCopied ); |
404 | Context()->Replace ( V2o, V2 ); |
405 | } |
406 | |
407 | //collect NM vertices |
408 | |
1d47d8d0 |
409 | Standard_Real af = 0.,al = 0.; |
7fd59977 |
410 | Handle(Geom_Curve) c3d; |
411 | Adaptor3d_CurveOnSurface AdCS; |
412 | if(myEdgeDivide->HasCurve3d()) |
413 | sae.Curve3d(E,c3d,af,al,Standard_False); |
414 | else if(myEdgeDivide->HasCurve2d() && !Surf.IsNull()) { |
415 | Handle(Geom2d_Curve) c2d; |
416 | sae.PCurve ( E, myFace, c2d, af, al, Standard_False); |
543a9964 |
417 | Handle(Adaptor3d_HSurface) AdS = new GeomAdaptor_HSurface(Surf); |
418 | Handle(Adaptor2d_HCurve2d) AC2d = new Geom2dAdaptor_HCurve(c2d,af,al); |
7fd59977 |
419 | AdCS.Load(AC2d); |
420 | AdCS.Load(AdS); |
421 | } |
422 | TopTools_SequenceOfShape aSeqNMVertices; |
423 | TColStd_SequenceOfReal aSeqParNM; |
424 | TopoDS_Iterator aItv(E,Standard_False); |
425 | ShapeAnalysis_Curve sac; |
426 | for ( ; aItv.More() ; aItv.Next()) { |
427 | if(aItv.Value().Orientation() == TopAbs_INTERNAL || |
428 | aItv.Value().Orientation() == TopAbs_EXTERNAL) { |
429 | TopoDS_Vertex aVold = TopoDS::Vertex(aItv.Value()); |
430 | aSeqNMVertices.Append(aVold); |
431 | gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aVold)); |
432 | Standard_Real ppar; |
433 | gp_Pnt pproj; |
434 | if(!c3d.IsNull()) |
435 | sac.Project(c3d,aP,Precision(),pproj,ppar,af,al,Standard_False); |
436 | else |
437 | sac.Project(AdCS,aP,Precision(),pproj,ppar); |
438 | aSeqParNM.Append(ppar); |
439 | } |
440 | } |
441 | |
442 | // creating new edge(s) |
443 | Handle(TColGeom_HArray1OfCurve) theSegments3d; |
444 | if(myEdgeDivide->HasCurve3d()) theSegments3d = theSplit3dTool->GetCurves(); |
445 | |
446 | Standard_Integer nbc = 0; |
447 | if (!theSegments3d.IsNull()) { |
448 | nbc = theSegments3d->Length(); |
449 | if ( !theSegments2d.IsNull() ) { |
450 | Standard_Integer nbc2d = theSegments2d->Length(); |
451 | if (nbc!=nbc2d) { |
0797d9d3 |
452 | #ifdef OCCT_DEBUG |
7fd59977 |
453 | cout<<"Error: Number of intervals are not equal for 2d 3d. Ignored."<<endl; |
454 | #endif |
455 | nbc = Min( nbc,nbc2d); |
456 | } |
457 | } |
458 | } |
459 | else |
460 | if(!theSegments2d.IsNull())// if theSegments have different length ??? |
461 | nbc = theSegments2d->Length(); |
462 | |
463 | if ( nbc <= 1 && ! theSplit3dTool->Status ( ShapeExtend_DONE ) && |
464 | ! theSplit2dTool->Status ( ShapeExtend_DONE ) ) { |
465 | B.Add ( newWire, E ); |
466 | continue; |
467 | } |
468 | |
469 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
470 | |
471 | TopoDS_Wire resWire; |
472 | B.MakeWire (resWire); |
473 | // TopoDS_Vertex firstVertex, lastVertex; |
474 | Standard_Integer numE =0; |
475 | gp_Pnt pntV1 = BRep_Tool::Pnt(V1); |
476 | //gp_Pnt pntV2 = BRep_Tool::Pnt(V2); // pntV2 not used - see below (skl) |
7fd59977 |
477 | //Standard_Real V2Tol = LimitTolerance( BRep_Tool::Tolerance(V2) ); // V2Tol not used - see below (skl) |
478 | |
479 | Handle(ShapeUpgrade_FixSmallCurves) FixSmallCurveTool = GetFixSmallCurveTool(); //gka Precision |
480 | FixSmallCurveTool->SetMinTolerance(MinTolerance()); |
481 | FixSmallCurveTool->Init(E, myFace); |
482 | FixSmallCurveTool->SetSplitCurve3dTool(theSplit3dTool); |
483 | FixSmallCurveTool->SetSplitCurve2dTool(theSplit2dTool); |
484 | FixSmallCurveTool->SetPrecision(MinTolerance()); |
485 | Standard_Integer Savnum =0; |
486 | Standard_Real SavParf; |
487 | Standard_Integer Small = 0; |
488 | for ( Standard_Integer icurv = 1; icurv <= nbc; icurv++ ) { |
489 | |
490 | Handle(Geom_Curve) theNewCurve3d; |
491 | if(!theSegments3d.IsNull()) theNewCurve3d = theSegments3d->Value(icurv); |
492 | |
493 | Handle(Geom2d_Curve) theNewPCurve1; |
494 | if(!theSegments2d.IsNull()) theNewPCurve1 = theSegments2d->Value(icurv); |
495 | Handle(Geom2d_Curve) revPCurve; |
496 | if(isSeam) |
497 | revPCurve = theSegments2dR->Value(icurv); |
498 | // construction of the intermediate Vertex |
499 | TopoDS_Vertex V; |
500 | if ( icurv <= nbc && nbc != 1 && ! isDeg ) { |
501 | Standard_Real par,parf /*,SavParl*/; |
502 | //Standard_Real SaveParf; // SaveParf not used - see below (skl) |
503 | gp_Pnt P,P1,PM; |
504 | // if edge has 3d curve, take point from it |
505 | if ( ! theNewCurve3d.IsNull() ) { |
506 | if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { |
507 | par = theNewCurve3d->LastParameter(); |
508 | parf = theNewCurve3d->FirstParameter(); |
509 | } |
510 | else { |
511 | par = theKnots3d->Value (icurv + 1); |
512 | parf = theKnots3d->Value (icurv); |
513 | } |
514 | P = theNewCurve3d->Value (par); |
515 | P1 = theNewCurve3d->Value (parf); |
516 | PM = theNewCurve3d->Value ((parf+par)/2); |
517 | } |
518 | // else use pcurve and surface (suppose that both exist) |
519 | else { |
520 | if ( Surf.IsNull() ) Surf = BRep_Tool::Surface ( myFace, Loc ); |
521 | if ( theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) ) { |
522 | par = theNewPCurve1->LastParameter(); |
523 | parf = theNewPCurve1->FirstParameter(); |
524 | } |
525 | else { |
526 | par = theKnots2d->Value (icurv + 1); |
527 | parf = theKnots2d->Value (icurv); |
528 | } |
529 | gp_Pnt2d p2d = theNewPCurve1->Value (par); |
530 | gp_Pnt2d p2df = theNewPCurve1->Value (parf); |
531 | gp_Pnt2d p2dM = theNewPCurve1->Value ((parf+par)/2); |
532 | P = Surf->Value ( p2d.X(), p2d.Y() ); |
533 | P1 = Surf->Value ( p2df.X(), p2df.Y() ); |
534 | PM = Surf->Value ( p2dM.X(), p2dM.Y() ); |
535 | P.Transform ( Loc.Transformation() ); |
536 | P1.Transform ( Loc.Transformation() ); |
537 | PM.Transform ( Loc.Transformation() ); |
538 | } |
539 | if(P.Distance(pntV1) < MinTolerance() && P.Distance(PM) < MinTolerance() && !myFace.IsNull()) { |
540 | if(!Small) { |
541 | SavParf = parf; |
542 | Savnum = icurv; |
543 | } |
544 | //SavParl = par; |
545 | Small++; |
546 | if(icurv == nbc) { |
547 | TopoDS_Vertex VVV = V1; |
548 | VVV.Orientation ( V2.Orientation() ); |
549 | Context()->Replace(V2,VVV); |
550 | } |
551 | continue; |
552 | } |
553 | if(Small) { |
554 | if(P.Distance(P1) > MinTolerance() || P.Distance(PM) > MinTolerance()) { |
555 | //FixSmallCurveTool->Perform(prevEdge,theNewCurve3d,theNewPCurve1,revPCurve,SavParf,SavParl); |
556 | gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() ); |
557 | B.UpdateVertex(V1,pmid,0); |
558 | } |
559 | else { |
560 | Handle(Geom_Curve) atmpCurve; |
561 | Handle(Geom2d_Curve) atmpCurve2d1,atmprepcurve; |
562 | if(FixSmallCurveTool->Approx( atmpCurve,atmpCurve2d1,atmprepcurve,SavParf,par)) { //BRepTools |
563 | theNewCurve3d = atmpCurve; |
564 | theNewPCurve1 = atmpCurve2d1; |
565 | revPCurve = atmprepcurve; |
566 | } |
567 | else { |
568 | gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() ); |
569 | B.UpdateVertex(V1,pmid,0); |
570 | } |
571 | } |
572 | Small =0; |
573 | } |
574 | //pdn |
575 | /* if(P.Distance (pntV1) < V1Tol) |
576 | V = V1; |
577 | else if (P.Distance (pntV2) < V2Tol) { |
578 | V = V2; |
579 | V1Tol = V2Tol; |
580 | pntV1 = pntV2; |
581 | } |
582 | else {*/ |
583 | if(icurv != nbc) { |
584 | B.MakeVertex (V, P, TolEdge); //tolerance of the edge |
585 | pntV1 = P; |
7fd59977 |
586 | } |
587 | else V = V2; |
588 | // else V2; |
589 | // } |
590 | // if (ShapeUpgrade::Debug()) cout <<"... New intermediate Vertex (" |
591 | // <<P.X()<<","<<P.Y()<<","<<P.Z()<<") :"<<(void*) &(*V.TShape()) |
592 | // <<" with Tolerance "<<TolEdge <<endl; |
593 | } |
594 | //else V = V2; |
595 | |
596 | TopoDS_Edge newEdge; |
597 | ShapeBuild_Edge sbe; |
598 | if ( isForward ) { |
599 | V1.Orientation ( TopAbs_FORWARD ); |
600 | V.Orientation ( TopAbs_REVERSED ); |
601 | newEdge = sbe.CopyReplaceVertices ( E, V1, V ); |
602 | } |
603 | else { |
604 | V1.Orientation ( TopAbs_REVERSED ); |
605 | V.Orientation ( TopAbs_FORWARD ); |
606 | newEdge = sbe.CopyReplaceVertices ( E, V, V1 ); |
607 | } |
608 | sbe.CopyPCurves ( newEdge, E ); |
609 | if(!theNewCurve3d.IsNull()) |
610 | B.UpdateEdge ( newEdge, theNewCurve3d, 0. ); |
611 | else if ( isDeg ) |
612 | B.Degenerated( newEdge, Standard_True); |
613 | //if(isSeam) { |
614 | // Handle(Geom2d_Curve) revPCurve = theSegments2dR->Value(icurv); |
615 | //if(newEdge.Orientation()==TopAbs_FORWARD) |
616 | //B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. ); |
617 | //else |
618 | //B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. ); |
619 | //} |
620 | //else if ( ! myFace.IsNull() ) |
621 | //B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. ); |
622 | |
623 | Standard_Real f3d = 0., l3d =0.; |
624 | if(!Savnum) Savnum = icurv; |
625 | Standard_Boolean srNew; |
626 | if(!theNewCurve3d.IsNull()) { |
627 | if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { |
628 | f3d = theNewCurve3d->FirstParameter(); |
629 | l3d = theNewCurve3d->LastParameter(); |
630 | srNew = ((f3d == theKnots3d->Value (Savnum)) && (l3d == theKnots3d->Value (icurv + 1))); |
631 | } |
632 | else { |
633 | f3d = theKnots3d->Value (Savnum); |
634 | l3d = theKnots3d->Value (icurv + 1); |
635 | srNew = Standard_True; |
636 | } |
637 | } |
638 | else |
639 | srNew = Standard_True; |
640 | |
641 | Standard_Real f2d=0, l2d=0; |
642 | if(!theNewPCurve1.IsNull()){ |
643 | if(theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) { |
644 | f2d = theNewPCurve1->FirstParameter(); |
645 | l2d = theNewPCurve1->LastParameter(); |
646 | srNew &= ((f2d == theKnots2d->Value (Savnum)) && (l2d == theKnots2d->Value (icurv + 1))); |
647 | } |
648 | else { |
649 | f2d = theKnots2d->Value (Savnum); |
650 | l2d = theKnots2d->Value (icurv + 1); |
651 | } |
652 | } |
653 | //if(!Savnum) Savnum = icurv; |
654 | if(!theNewCurve3d.IsNull()) |
655 | theTransferParamTool->TransferRange(newEdge,theKnots3d->Value (Savnum),theKnots3d->Value (icurv + 1),Standard_False); |
656 | else |
657 | theTransferParamTool->TransferRange(newEdge,theKnots2d->Value (Savnum),theKnots2d->Value (icurv + 1),Standard_True); |
658 | /* |
659 | Standard_Real alpha = (theKnots3d->Value (icurv) - f)/(l - f); |
660 | Standard_Real beta = (theKnots3d->Value (icurv + 1) - f)/(l - f); |
661 | sbe.CopyRanges(newEdge,E, alpha, beta);*/ |
662 | Savnum =0; |
663 | Handle(Geom2d_Curve) c2dTmp; |
664 | Standard_Real setF, setL; |
665 | if( ! myFace.IsNull() && sae.PCurve (newEdge, myFace, c2dTmp, setF, setL, Standard_False)) |
666 | srNew &= ( (setF==f2d) && (setL==l2d) ); |
667 | |
668 | if(isSeam) { |
669 | // Handle(Geom2d_Curve revPCurve = theSegments2dR->Value(icurv); |
670 | if(newEdge.Orientation()==TopAbs_FORWARD) |
671 | B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. ); |
672 | else |
673 | B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. ); |
674 | } |
675 | else if ( ! myFace.IsNull() ) { |
676 | B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. ); |
677 | } |
678 | |
679 | if(!theNewCurve3d.IsNull()) |
680 | sbe.SetRange3d(newEdge,f3d,l3d); |
681 | if(!theNewPCurve1.IsNull()) |
682 | B.Range ( newEdge, myFace, f2d, l2d); |
683 | if((!wasSR || !srNew)&&!BRep_Tool::Degenerated(newEdge) ) |
684 | B.SameRange(newEdge, Standard_False); |
685 | |
686 | //addition NM vertices to new edges |
687 | Standard_Real afpar = (myEdgeDivide->HasCurve3d() ? f3d : f2d); |
688 | |
689 | Standard_Real alpar = (myEdgeDivide->HasCurve3d() ? l3d: l2d); |
690 | Standard_Integer n =1; |
691 | for( ; n <= aSeqParNM.Length(); n++) { |
692 | Standard_Real apar = aSeqParNM.Value(n); |
693 | TopoDS_Vertex aVold = TopoDS::Vertex(aSeqNMVertices.Value(n)); |
694 | TopoDS_Vertex aNMVer =ShapeAnalysis_TransferParametersProj::CopyNMVertex(aVold,newEdge,E); |
695 | Context()->Replace(aVold,aNMVer); |
696 | if(fabs(apar - afpar) <= Precision::PConfusion()) |
697 | Context()->Replace(aNMVer,V1); |
698 | else if(fabs(apar - alpar) <= Precision::PConfusion()) |
699 | Context()->Replace(aNMVer,V); |
700 | else if( apar > afpar && apar <alpar) |
701 | B.Add (newEdge,aNMVer); |
702 | else continue; |
703 | aSeqNMVertices.Remove(n); |
704 | aSeqParNM.Remove(n); |
705 | n--; |
706 | } |
707 | |
708 | |
709 | // if (ShapeUpgrade::Debug()) cout <<"... New Edge " |
710 | // <<(void*) &(*newEdge.TShape())<<" on vertices " |
711 | // <<(void*) &(*V1.TShape())<<", " <<(void*) &(*V.TShape()) |
712 | // <<" with Tolerance "<<TolEdge <<endl; |
713 | B.Add ( resWire, newEdge ); |
714 | B.Add ( newWire, newEdge ); |
715 | numE++; |
716 | V1 = V; |
717 | } |
718 | if(numE) |
ab860031 |
719 | { |
720 | resWire.Closed (BRep_Tool::IsClosed (resWire)); |
7fd59977 |
721 | Context()->Replace(E,resWire); |
ab860031 |
722 | } |
7fd59977 |
723 | else |
724 | Context()->Remove(E); |
725 | } |
726 | } |
727 | if ( Status ( ShapeExtend_DONE ) ) { |
728 | //smh#8 |
ab860031 |
729 | newWire.Closed (BRep_Tool::IsClosed (newWire)); |
7fd59977 |
730 | TopoDS_Shape tmpW = Context()->Apply ( newWire ).Oriented(myWire.Orientation()); |
731 | myWire = TopoDS::Wire (tmpW ); |
732 | } |
733 | } |
734 | |
735 | //======================================================================= |
736 | //function : Face |
737 | //purpose : |
738 | //======================================================================= |
739 | |
740 | const TopoDS_Wire& ShapeUpgrade_WireDivide::Wire() const |
741 | { |
742 | return myWire; |
743 | } |
744 | |
745 | //======================================================================= |
746 | //function : Status |
747 | //purpose : |
748 | //======================================================================= |
749 | |
750 | Standard_Boolean ShapeUpgrade_WireDivide::Status (const ShapeExtend_Status status) const |
751 | { |
752 | return ShapeExtend::DecodeStatus ( myStatus, status ); |
753 | } |
754 | |
755 | //======================================================================= |
756 | //function : SetSplitCurve3dTool |
757 | //purpose : |
758 | //======================================================================= |
759 | |
760 | void ShapeUpgrade_WireDivide::SetSplitCurve3dTool(const Handle(ShapeUpgrade_SplitCurve3d)& splitCurve3dTool) |
761 | { |
762 | mySplitCurve3dTool = splitCurve3dTool; |
763 | } |
764 | |
765 | //======================================================================= |
766 | //function : SetSplitCurve2dTool |
767 | //purpose : |
768 | //======================================================================= |
769 | |
770 | void ShapeUpgrade_WireDivide::SetSplitCurve2dTool(const Handle(ShapeUpgrade_SplitCurve2d)& splitCurve2dTool) |
771 | { |
772 | mySplitCurve2dTool = splitCurve2dTool; |
773 | } |
774 | |
775 | //======================================================================= |
776 | //function : GetSplitCurve3dTool |
777 | //purpose : |
778 | //======================================================================= |
779 | |
780 | Handle(ShapeUpgrade_SplitCurve3d) ShapeUpgrade_WireDivide::GetSplitCurve3dTool() const |
781 | { |
782 | return mySplitCurve3dTool; |
783 | } |
784 | |
785 | //======================================================================= |
786 | //function : GetSplitCurve2dTool |
787 | //purpose : |
788 | //======================================================================= |
789 | |
790 | Handle(ShapeUpgrade_SplitCurve2d) ShapeUpgrade_WireDivide::GetSplitCurve2dTool() const |
791 | { |
792 | return mySplitCurve2dTool; |
793 | } |
794 | |
795 | //======================================================================= |
796 | //function : SetEdgeDivideTool |
797 | //purpose : |
798 | //======================================================================= |
799 | |
800 | void ShapeUpgrade_WireDivide::SetEdgeDivideTool(const Handle (ShapeUpgrade_EdgeDivide)& edgeDivideTool) |
801 | { |
802 | myEdgeDivide = edgeDivideTool; |
803 | } |
804 | |
805 | //======================================================================= |
806 | //function : GetEdgeDivideTool |
807 | //purpose : |
808 | //======================================================================= |
809 | |
810 | Handle (ShapeUpgrade_EdgeDivide) ShapeUpgrade_WireDivide::GetEdgeDivideTool() const |
811 | { |
812 | return myEdgeDivide; |
813 | } |
814 | |
815 | //======================================================================= |
816 | //function : SetTransferParamTool |
817 | //purpose : |
818 | //======================================================================= |
819 | |
820 | void ShapeUpgrade_WireDivide::SetTransferParamTool(const Handle(ShapeAnalysis_TransferParameters)& TransferParam) |
821 | { |
822 | myTransferParamTool = TransferParam; |
823 | } |
824 | |
825 | //======================================================================= |
826 | //function : GetTransferParamTool |
827 | //purpose : |
828 | //======================================================================= |
829 | |
830 | Handle(ShapeAnalysis_TransferParameters) ShapeUpgrade_WireDivide::GetTransferParamTool() |
831 | { |
832 | return myTransferParamTool; |
833 | } |
834 | |
835 | //======================================================================= |
836 | //function : SetEdgeMode |
837 | //purpose : |
838 | //======================================================================= |
839 | |
840 | void ShapeUpgrade_WireDivide::SetEdgeMode(const Standard_Integer EdgeMode) |
841 | { |
842 | myEdgeMode = EdgeMode; |
843 | } |
844 | |
845 | //======================================================================= |
846 | //function : SetFixSmallCurveTool |
847 | //purpose : |
848 | //======================================================================= |
849 | |
850 | void ShapeUpgrade_WireDivide::SetFixSmallCurveTool(const Handle(ShapeUpgrade_FixSmallCurves)& FixSmallCurvesTool) |
851 | { |
852 | myFixSmallCurveTool = FixSmallCurvesTool; |
853 | } |
854 | |
855 | //======================================================================= |
856 | //function : GetFixSmallCurveTool |
857 | //purpose : |
858 | //======================================================================= |
859 | |
860 | Handle(ShapeUpgrade_FixSmallCurves) ShapeUpgrade_WireDivide::GetFixSmallCurveTool() const |
861 | { |
862 | return myFixSmallCurveTool; |
863 | } |