1 // Created on: 1997-05-05
2 // Created by: Jerome LEMONIER
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modification de l'interface
18 // Amelioration de l'aglo de remplissage
19 // 29-09-97 ; jct; correction du calcul des points doublons (tol 2d et non 3d)
20 // 16-10-97 ; jct; on remet un Raise au lieu du cout sous debug (sinon plantage dans k1fab)
21 // 03-11-97 ; jct; plus de reference a BRepAdaptor et BRepTools
23 #include <Adaptor2d_HCurve2d.hxx>
24 #include <Adaptor3d_HCurve.hxx>
25 #include <Adaptor3d_CurveOnSurface.hxx>
26 #include <Approx_CurveOnSurface.hxx>
27 #include <Extrema_ExtPS.hxx>
28 #include <Extrema_POnSurf.hxx>
29 #include <GCPnts_AbscissaPoint.hxx>
30 #include <Geom2d_BezierCurve.hxx>
31 #include <Geom2d_BSplineCurve.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2dAdaptor_Curve.hxx>
34 #include <Geom2dInt_GInter.hxx>
35 #include <Geom_BSplineSurface.hxx>
36 #include <Geom_Plane.hxx>
37 #include <Geom_RectangularTrimmedSurface.hxx>
38 #include <Geom_Surface.hxx>
39 #include <GeomAdaptor.hxx>
40 #include <GeomAdaptor_HSurface.hxx>
41 #include <GeomAdaptor_Surface.hxx>
42 #include <GeomLProp_SLProps.hxx>
43 #include <GeomPlate_BuildAveragePlane.hxx>
44 #include <GeomPlate_BuildPlateSurface.hxx>
45 #include <GeomPlate_CurveConstraint.hxx>
46 #include <GeomPlate_HArray1OfSequenceOfReal.hxx>
47 #include <GeomPlate_MakeApprox.hxx>
48 #include <GeomPlate_PointConstraint.hxx>
49 #include <GeomPlate_SequenceOfAij.hxx>
50 #include <GeomPlate_Surface.hxx>
52 #include <gp_Pnt2d.hxx>
54 #include <gp_Vec2d.hxx>
55 #include <IntRes2d_IntersectionPoint.hxx>
56 #include <Law_Interpol.hxx>
57 #include <LocalAnalysis_SurfaceContinuity.hxx>
58 #include <Plate_D1.hxx>
59 #include <Plate_D2.hxx>
60 #include <Plate_FreeGtoCConstraint.hxx>
61 #include <Plate_GtoCConstraint.hxx>
62 #include <Plate_PinpointConstraint.hxx>
63 #include <Plate_Plate.hxx>
64 #include <Precision.hxx>
65 #include <ProjLib_CompProjectedCurve.hxx>
66 #include <ProjLib_HCompProjectedCurve.hxx>
67 #include <Standard_ConstructionError.hxx>
68 #include <Standard_RangeError.hxx>
69 #include <TColgp_Array1OfPnt2d.hxx>
70 #include <TColgp_HArray1OfPnt.hxx>
71 #include <TColgp_HArray2OfPnt.hxx>
72 #include <TColgp_SequenceOfVec.hxx>
73 #include <TColStd_HArray1OfReal.hxx>
74 #include <TColStd_SequenceOfInteger.hxx>
78 // pour les intersection entre les courbes
81 #include <DrawTrSurf.hxx>
82 #include <Draw_Marker3D.hxx>
83 #include <Draw_Marker2D.hxx>
86 // 1 : Display des Geometries et controle intermediaire
87 // 2 : Display du nombre de contrainte par courbe + Intersection
88 // 3 : Dump des contraintes dans Plate
89 static Standard_Integer NbPlan = 0;
90 //static Standard_Integer NbCurv2d = 0;
91 static Standard_Integer NbMark = 0;
92 static Standard_Integer NbProj = 0;
97 #include <OSD_Chronometer.hxx>
98 #include <Geom_Surface.hxx>
99 static Standard_Integer Affich=0;
102 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
103 // =========================================================
104 // C O N S T R U C T E U R S
105 // =========================================================
106 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
108 //---------------------------------------------------------
109 // Constructeur compatible avec l'ancienne version
110 //---------------------------------------------------------
111 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
112 const Handle(TColStd_HArray1OfInteger)& NPoints,
113 const Handle(GeomPlate_HArray1OfHCurve)& TabCurve,
114 const Handle(TColStd_HArray1OfInteger)& Tang,
115 const Standard_Integer Degree,
116 const Standard_Integer NbIter,
117 const Standard_Real Tol2d,
118 const Standard_Real Tol3d,
119 const Standard_Real TolAng,
120 const Standard_Real ,
121 const Standard_Boolean Anisotropie
123 myAnisotropie(Anisotropie),
131 { Standard_Integer NTCurve=TabCurve->Length();// Nombre de contraintes lineaires
132 myNbPtsOnCur = 0; // Debrayage du calcul du nombre de points
133 // en fonction de la longueur
134 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
135 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
137 throw Standard_ConstructionError("GeomPlate : Number of iteration must be >= 1");
140 throw Standard_ConstructionError("GeomPlate : the bounds Array is null");
141 if (Tang->Length()==0)
142 throw Standard_ConstructionError("GeomPlate : the constraints Array is null");
143 Standard_Integer nbp = 0;
145 for ( i=1;i<=NTCurve;i++)
146 { nbp+=NPoints->Value(i);
149 throw Standard_ConstructionError("GeomPlate : the resolution is impossible if the number of constraints points is 0");
151 throw Standard_ConstructionError("GeomPlate ; the degree resolution must be upper of 2");
152 // Remplissage des champs passage de l'ancien constructeur au nouveau
153 for(i=1;i<=NTCurve;i++)
154 { Handle(GeomPlate_CurveConstraint) Cont = new GeomPlate_CurveConstraint
155 ( TabCurve->Value(i),
158 myLinCont->Append(Cont);
160 mySurfInitIsGive=Standard_False;
162 myIsLinear = Standard_True;
163 myFree = Standard_False;
166 //------------------------------------------------------------------
167 // Constructeur avec surface d'init et degre de resolution de plate
168 //------------------------------------------------------------------
169 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
170 const Handle(Geom_Surface)& Surf,
171 const Standard_Integer Degree,
172 const Standard_Integer NbPtsOnCur,
173 const Standard_Integer NbIter,
174 const Standard_Real Tol2d,
175 const Standard_Real Tol3d,
176 const Standard_Real TolAng,
177 const Standard_Real /*TolCurv*/,
178 const Standard_Boolean Anisotropie ) :
180 myAnisotropie(Anisotropie),
182 myNbPtsOnCur(NbPtsOnCur),
190 throw Standard_ConstructionError("GeomPlate : Number of iteration must be >= 1");
192 throw Standard_ConstructionError("GeomPlate : the degree resolution must be upper of 2");
193 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
194 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
195 mySurfInitIsGive=Standard_True;
197 myIsLinear = Standard_True;
198 myFree = Standard_False;
202 //---------------------------------------------------------
203 // Constructeur avec degre de resolution de plate
204 //---------------------------------------------------------
205 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
206 const Standard_Integer Degree,
207 const Standard_Integer NbPtsOnCur,
208 const Standard_Integer NbIter,
209 const Standard_Real Tol2d,
210 const Standard_Real Tol3d,
211 const Standard_Real TolAng,
212 const Standard_Real /*TolCurv*/,
213 const Standard_Boolean Anisotropie ) :
214 myAnisotropie(Anisotropie),
216 myNbPtsOnCur(NbPtsOnCur),
224 throw Standard_ConstructionError("GeomPlate : Number of iteration must be >= 1");
226 throw Standard_ConstructionError("GeomPlate : the degree resolution must be upper of 2");
227 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
228 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
229 mySurfInitIsGive=Standard_False;
231 myIsLinear = Standard_True;
232 myFree = Standard_False;
235 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
236 // =========================================================
237 // M E T H O D E S P U B L I Q U E S
238 // =========================================================
239 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
243 //-------------------------------------------------------------------------
244 // Fonction : TrierTab, Fonction interne, ne fait partie de la classe
245 //-------------------------------------------------------------------------
246 // Reordonne le tableau des permutations
247 // Apres l'appel a CourbeJointive l'ordre des courbes est modifie
248 // Ex : ordre init des courbe ==> A B C D E F
249 // Dans TabInit on note ==> 1 2 3 4 5 6
250 // apres CourbeJointive ==> A E C B D F
251 // TabInit ==> 1 5 3 2 4 6
252 // apres TrierTab le Tableau contient ==> 1 4 3 5 2 6
253 // On peut ainsi acceder a la 2eme courbe en prenant TabInit[2]
254 // c'est a dire la 4eme du tableau des courbes classees
255 //-------------------------------------------------------------------------
256 void TrierTab(Handle(TColStd_HArray1OfInteger)& Tab)
257 { // Trie le tableau des permutations pour retrouver l'ordre initial
258 Standard_Integer Nb=Tab->Length();
259 TColStd_Array1OfInteger TabTri(1,Nb);
260 for (Standard_Integer i=1;i<=Nb;i++)
261 TabTri.SetValue(Tab->Value(i),i);
262 Tab->ChangeArray1()=TabTri;
265 //---------------------------------------------------------
266 // Fonction : ProjectCurve
267 //---------------------------------------------------------
268 Handle(Geom2d_Curve) GeomPlate_BuildPlateSurface::ProjectCurve(const Handle(Adaptor3d_HCurve)& Curv)
269 { // Projection d'une courbe sur un plan
270 Handle(Geom2d_Curve) Curve2d ;
271 Handle(GeomAdaptor_HSurface) hsur = new GeomAdaptor_HSurface(mySurfInit);
274 ProjLib_CompProjectedCurve Projector(hsur, Curv, myTol3d/10, myTol3d/10);
276 Standard_Real UdebCheck, UfinCheck, ProjUdeb, ProjUfin;
277 UdebCheck = Curv->FirstParameter();
278 UfinCheck = Curv->LastParameter();
279 Projector.Bounds( 1, ProjUdeb, ProjUfin );
281 if (Projector.NbCurves() != 1 ||
282 Abs( UdebCheck -ProjUdeb ) > Precision::PConfusion() ||
283 Abs( UfinCheck -ProjUfin ) > Precision::PConfusion())
285 if (Projector.IsSinglePnt(1, P2d))
287 //solution ponctuelles
288 TColgp_Array1OfPnt2d poles(1, 2);
290 Curve2d = new (Geom2d_BezierCurve) (poles);
294 Curve2d.Nullify(); // Pas de solution continue
296 cout << "BuildPlateSurace :: Pas de projection continue" << endl;
301 GeomAbs_Shape Continuity = GeomAbs_C1;
302 Standard_Integer MaxDegree = 10, MaxSeg;
303 Standard_Real Udeb, Ufin;
304 Handle(ProjLib_HCompProjectedCurve) HProjector =
305 new ProjLib_HCompProjectedCurve();
306 HProjector->Set(Projector);
307 Projector.Bounds(1, Udeb, Ufin);
309 MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
310 Approx_CurveOnSurface appr(HProjector, hsur, Udeb, Ufin, myTol3d,
311 Continuity, MaxDegree, MaxSeg,
312 Standard_False, Standard_True);
314 Curve2d = appr.Curve2d();
319 sprintf(name,"proj_%d",++NbProj);
320 DrawTrSurf::Set(name, Curve2d);
325 //---------------------------------------------------------
326 // Fonction : ProjectedCurve
327 //---------------------------------------------------------
328 Handle(Adaptor2d_HCurve2d) GeomPlate_BuildPlateSurface::ProjectedCurve( Handle(Adaptor3d_HCurve)& Curv)
329 { // Projection d'une courbe sur la surface d'init
331 Handle(GeomAdaptor_HSurface) hsur = new GeomAdaptor_HSurface(mySurfInit);
333 ProjLib_CompProjectedCurve Projector(hsur, Curv, myTolU/10, myTolV/10);
334 Handle(ProjLib_HCompProjectedCurve) HProjector =
335 new ProjLib_HCompProjectedCurve();
337 if (Projector.NbCurves() != 1) {
339 HProjector.Nullify(); // Pas de solution continue
341 cout << "BuildPlateSurace :: Pas de projection continue" << endl;
346 Standard_Real First1,Last1,First2,Last2;
347 First1=Curv->FirstParameter();
348 Last1 =Curv->LastParameter();
349 Projector.Bounds(1,First2,Last2);
351 if (Abs(First1-First2) <= Max(myTolU,myTolV) &&
352 Abs(Last1-Last2) <= Max(myTolU,myTolV))
355 HProjector->Set(Projector);
356 HProjector = Handle(ProjLib_HCompProjectedCurve)::
357 DownCast(HProjector->Trim(First2,Last2,Precision::PConfusion()));
361 HProjector.Nullify(); // Pas de solution continue
363 cout << "BuildPlateSurace :: Pas de projection complete" << endl;
370 //---------------------------------------------------------
371 // Fonction : ProjectPoint
372 //---------------------------------------------------------
373 // Projete une point sur la surface d'init
374 //---------------------------------------------------------
375 gp_Pnt2d GeomPlate_BuildPlateSurface::ProjectPoint(const gp_Pnt &p3d)
378 Standard_Integer nearest = 1;
379 if( myProj.NbExt() > 1)
381 Standard_Real dist2mini = myProj.SquareDistance(1);
382 for (Standard_Integer i=2; i<=myProj.NbExt();i++)
384 if (myProj.SquareDistance(i) < dist2mini)
386 dist2mini = myProj.SquareDistance(i);
391 P=myProj.Point(nearest);
399 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
400 // =========================================================
401 // M E T H O D E S P U B L I Q U E S
402 // =========================================================
403 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
404 //---------------------------------------------------------
406 //---------------------------------------------------------
407 // Initialise les contraintes lineaires et ponctuelles
408 //---------------------------------------------------------
409 void GeomPlate_BuildPlateSurface::Init()
410 { myLinCont->Clear();
412 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
413 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
416 //---------------------------------------------------------
417 // Fonction : LoadInitSurface
418 //---------------------------------------------------------
419 // Charge la surface initiale
420 //---------------------------------------------------------
421 void GeomPlate_BuildPlateSurface::LoadInitSurface(const Handle(Geom_Surface)& Surf)
423 mySurfInitIsGive=Standard_True;
426 //---------------------------------------------------------
428 //---------------------------------------------------------
429 //---------------------------------------------------------
430 // Ajout d'une contrainte lineaire
431 //---------------------------------------------------------
432 void GeomPlate_BuildPlateSurface::
433 Add(const Handle(GeomPlate_CurveConstraint)& Cont)
434 { myLinCont->Append(Cont);
437 void GeomPlate_BuildPlateSurface::SetNbBounds( const Standard_Integer NbBounds )
439 myNbBounds = NbBounds;
442 //---------------------------------------------------------
444 //---------------------------------------------------------
445 //---------------------------------------------------------
446 // Ajout d'une contrainte ponctuelle
447 //---------------------------------------------------------
448 void GeomPlate_BuildPlateSurface::
449 Add(const Handle(GeomPlate_PointConstraint)& Cont)
451 myPntCont->Append(Cont);
454 //---------------------------------------------------------
456 // Calcul la surface de remplissage avec les contraintes chargees
457 //---------------------------------------------------------
458 void GeomPlate_BuildPlateSurface::Perform()
462 OSD_Chronometer Chrono;
468 myNbBounds = myLinCont->Length();
471 //=====================================================================
472 //Declaration des variables.
473 //=====================================================================
474 Standard_Integer NTLinCont = myLinCont->Length(),
475 NTPntCont = myPntCont->Length(), NbBoucle=0;
476 // La variable NTPoint peut etre enlevee
477 Standard_Boolean Fini=Standard_True;
478 if ((NTLinCont + NTPntCont) == 0)
481 cout << "WARNING : GeomPlate : The number of constraints is null." << endl;
487 //======================================================================
489 //======================================================================
490 if (!mySurfInitIsGive)
495 { // Tableau des permutations pour conserver l'ordre initial voir TrierTab
496 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
497 for (Standard_Integer l=1;l<=NTLinCont;l++)
498 myInitOrder->SetValue(l,l);
499 if (!CourbeJointive(myTol3d))
500 {// throw Standard_Failure("Curves are not joined");
502 cout<<"WARNING : Courbes non jointives a "<<myTol3d<<" pres"<<endl;
505 TrierTab(myInitOrder); // Reordonne le tableau des permutations
507 else if(NTLinCont > 0)//Patch
509 mySense = new TColStd_HArray1OfInteger( 1, NTLinCont, 0 );
510 myInitOrder = new TColStd_HArray1OfInteger( 1, NTLinCont, 1 );
514 if (mySurfInit.IsNull())
519 Standard_Real u1,v1,u2,v2;
520 mySurfInit->Bounds(u1,v1,u2,v2);
521 GeomAdaptor_Surface aSurfInit(mySurfInit);
522 myTolU = aSurfInit.UResolution(myTol3d);
523 myTolV = aSurfInit.VResolution(myTol3d);
524 myProj.Initialize(aSurfInit,u1,v1,u2,v2,
527 //======================================================================
528 // Projection des courbes
529 //======================================================================
530 Standard_Boolean Ok = Standard_True;
531 for (Standard_Integer i = 1; i <= NTLinCont; i++)
532 if(myLinCont->Value(i)->Curve2dOnSurf().IsNull())
534 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
535 if (Curve2d.IsNull())
540 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
544 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
549 mySurfInit = App.Surface();
551 mySurfInit->Bounds(u1,v1,u2,v2);
552 GeomAdaptor_Surface Surf(mySurfInit);
553 myTolU = Surf.UResolution(myTol3d);
554 myTolV = Surf.VResolution(myTol3d);
555 myProj.Initialize(Surf,u1,v1,u2,v2,
559 for (Standard_Integer i = 1; i <= NTLinCont; i++)
561 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
562 if (Curve2d.IsNull())
567 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
571 mySurfInit = myPlanarSurfInit;
573 mySurfInit->Bounds(u1,v1,u2,v2);
574 GeomAdaptor_Surface SurfNew(mySurfInit);
575 myTolU = SurfNew.UResolution(myTol3d);
576 myTolV = SurfNew.VResolution(myTol3d);
577 myProj.Initialize(SurfNew,u1,v1,u2,v2,
580 for (Standard_Integer i = 1; i <= NTLinCont; i++)
581 myLinCont->ChangeValue(i)->
582 SetCurve2dOnSurf(ProjectCurve( myLinCont->Value(i)->Curve3d() ) );
584 else { // Project the points
585 for (Standard_Integer i=1; i<=NTPntCont; i++) {
587 myPntCont->Value(i)->D0(P);
588 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
593 //======================================================================
594 // Projection des points
595 //======================================================================
596 for (Standard_Integer i=1;i<=NTPntCont;i++) {
597 if (! myPntCont->Value(i)->HasPnt2dOnSurf()) {
599 myPntCont->Value(i)->D0(P);
600 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
604 //======================================================================
605 // Nbre de point par courbe
606 //======================================================================
607 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
610 //======================================================================
611 // Gestion des incompatibilites entre courbes
612 //======================================================================
613 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
614 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
615 if (NTLinCont != 0) {
616 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
617 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
618 Intersect(PntInter, PntG1G1);
621 //======================================================================
622 // Boucle pour obtenir une meilleur surface
623 //======================================================================
625 myFree = !myIsLinear;
630 if (Affich && NbBoucle) {
631 cout<<"Resultats boucle"<< NbBoucle << endl;
632 cout<<"DistMax="<<myG0Error<<endl;
634 cout<<"AngleMax="<<myG1Error<<endl;
636 cout<<"CourbMax="<<myG2Error<<endl;
641 { //====================================================================
642 // Calcul le nombre de point total et le maximum de points par courbe
643 //====================================================================
644 Standard_Integer NPointMax=0;
645 for (Standard_Integer i=1;i<=NTLinCont;i++)
646 if ((myLinCont->Value(i)->NbPoints())>NPointMax)
647 NPointMax=(Standard_Integer )( myLinCont->Value(i)->NbPoints());
648 //====================================================================
649 // Discretisation des courbes
650 //====================================================================
651 Discretise(PntInter, PntG1G1);
652 //====================================================================
653 //Preparation des points de contrainte pour plate
654 //====================================================================
655 LoadCurve( NbBoucle );
656 if ( myPntCont->Length() != 0)
657 LoadPoint( NbBoucle );
658 //====================================================================
659 //Resolution de la surface
660 //====================================================================
661 myPlate.SolveTI(myDegree, ComputeAnisotropie());
662 if (!myPlate.IsDone())
665 cout << "WARNING : GeomPlate : abort calcul of Plate." << endl;
671 myGeomPlateSurface = new GeomPlate_Surface(mySurfInit,myPlate);
672 Standard_Real Umin,Umax,Vmin,Vmax;
673 myPlate.UVBox(Umin,Umax,Vmin,Vmax);
674 myGeomPlateSurface->SetBounds(Umin,Umax,Vmin,Vmax);
676 Fini = VerifSurface(NbBoucle);
677 if ((NbBoucle >= myNbIter)&&(!Fini))
680 cout<<"Warning objectif non atteint"<<endl;
682 Fini = Standard_True;
685 if ((NTPntCont != 0)&&(Fini))
686 { Standard_Real di,an,cu;
687 VerifPoints(di,an,cu);
691 { LoadPoint( NbBoucle );
692 //====================================================================
693 //Resolution de la surface
694 //====================================================================
695 myPlate.SolveTI(myDegree, ComputeAnisotropie());
696 if (!myPlate.IsDone())
699 cout << "WARNING : GeomPlate : abort calcul of Plate." << endl;
704 myGeomPlateSurface = new GeomPlate_Surface(mySurfInit,myPlate);
705 Standard_Real Umin,Umax,Vmin,Vmax;
706 myPlate.UVBox(Umin,Umax,Vmin,Vmax);
707 myGeomPlateSurface->SetBounds(Umin,Umax,Vmin,Vmax);
708 Fini = Standard_True;
709 Standard_Real di,an,cu;
710 VerifPoints(di,an,cu);
712 } while (!Fini); // Fin boucle pour meilleur surface
715 { cout<<"======== Resultats globaux ==========="<<endl;
716 cout<<"DistMax="<<myG0Error<<endl;
718 cout<<"AngleMax="<<myG1Error<<endl;
720 cout<<"CourbMax="<<myG2Error<<endl;
725 cout<<"*** FIN DE GEOMPLATE ***"<<endl;
726 cout<<"Temps de calcul : "<<Tps<<endl;
727 cout<<"Nombre de boucle : "<<NbBoucle<<endl;
731 //---------------------------------------------------------
732 // fonction : EcartContraintesMIL
733 //---------------------------------------------------------
734 void GeomPlate_BuildPlateSurface::
735 EcartContraintesMil ( const Standard_Integer c,
736 Handle(TColStd_HArray1OfReal)& d,
737 Handle(TColStd_HArray1OfReal)& an,
738 Handle(TColStd_HArray1OfReal)& courb)
740 Standard_Integer NbPt=myParCont->Value(c).Length();
745 NbPt=myParCont->Value(c).Length();
746 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
748 gp_Pnt2d P2d;Standard_Integer i;
749 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(c);
750 switch (LinCont->Order())
752 for (i=1; i<NbPt; i++)
753 { U = ( myParCont->Value(c).Value(i) +
754 myParCont->Value(c).Value(i+1) )/2;
756 if (!LinCont->ProjectedCurve().IsNull())
757 P2d = LinCont->ProjectedCurve()->Value(U);
759 { if (!LinCont->Curve2dOnSurf().IsNull())
760 P2d = LinCont->Curve2dOnSurf()->Value(U);
762 P2d = ProjectPoint(Pi);
764 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
767 d->ChangeValue(i) = Pf.Distance(Pi);
771 for (i=1; i<NbPt; i++)
772 { U = ( myParCont->Value(c).Value(i) +
773 myParCont->Value(c).Value(i+1) )/2;
774 LinCont->D1(U, Pi, v1i, v2i);
775 if (!LinCont->ProjectedCurve().IsNull())
776 P2d = LinCont->ProjectedCurve()->Value(U);
778 { if (!LinCont->Curve2dOnSurf().IsNull())
779 P2d = LinCont->Curve2dOnSurf()->Value(U);
781 P2d = ProjectPoint(Pi);
783 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
784 d->ChangeValue(i) = Pf.Distance(Pi);
785 v3i = v1i^v2i; v3f=v1f^v2f;
786 Standard_Real angle=v3f.Angle(v3i);
788 an->ChangeValue(i) = M_PI -angle;
790 an->ChangeValue(i) = angle;
795 Handle(Geom_Surface) Splate (myGeomPlateSurface);
796 LocalAnalysis_SurfaceContinuity CG2;
797 for (i=1; i<NbPt; i++)
798 { U = ( myParCont->Value(c).Value(i) +
799 myParCont->Value(c).Value(i+1) )/2;
801 if (!LinCont->ProjectedCurve().IsNull())
802 P2d = LinCont->ProjectedCurve()->Value(U);
804 { if (!LinCont->Curve2dOnSurf().IsNull())
805 P2d = LinCont->Curve2dOnSurf()->Value(U);
807 P2d = ProjectPoint(Pi);
809 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
811 CG2.ComputeAnalysis(Prop, myLinCont->Value(c)->LPropSurf(U),
813 d->ChangeValue(i)=CG2.C0Value();
814 an->ChangeValue(i)=CG2.G1Angle();
815 courb->ChangeValue(i)=CG2.G2CurvatureGap();
823 //---------------------------------------------------------
824 // fonction : Disc2dContour
825 //---------------------------------------------------------
826 void GeomPlate_BuildPlateSurface::
827 Disc2dContour ( const Standard_Integer /*nbp*/,
828 TColgp_SequenceOfXY& Seq2d)
831 if (Seq2d.Length()!=4)
832 cout<<"nbp doit etre egal a 4 pour Disc2dContour"<<endl;
837 // echantillonnage en "cosinus" + 3 points sur chaque intervalle
838 Standard_Integer NTCurve = myLinCont->Length();
839 Standard_Integer NTPntCont = myPntCont->Length();
843 Standard_Real u1,v1,u2,v2;
846 mySurfInit->Bounds(u1,v1,u2,v2);
847 GeomAdaptor_Surface Surf(mySurfInit);
848 myProj.Initialize(Surf,u1,v1,u2,v2,
851 for( i=1; i<=NTPntCont; i++)
852 if (myPntCont->Value(i)->Order()!=-1)
853 { P2d = myPntCont->Value(i)->Pnt2dOnSurf();
854 UV.SetX(P2d.Coord(1));
855 UV.SetY(P2d.Coord(2));
858 for(i=1; i<=NTCurve; i++)
860 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(i);
861 if (LinCont->Order()!=-1)
862 { Standard_Integer NbPt=myParCont->Value(i).Length();
863 // premier point de contrainte (j=0)
864 if (!LinCont->ProjectedCurve().IsNull())
865 P2d = LinCont->ProjectedCurve()->Value(myParCont->Value(i).Value(1));
868 { if (!LinCont->Curve2dOnSurf().IsNull())
869 P2d = LinCont->Curve2dOnSurf()->Value(myParCont->Value(i).Value(1));
873 LinCont->D0(myParCont->Value(i).Value(1),PP);
874 P2d = ProjectPoint(PP);
878 UV.SetX(P2d.Coord(1));
879 UV.SetY(P2d.Coord(2));
881 for (Standard_Integer j=2; j<NbPt; j++)
882 { Standard_Real Uj=myParCont->Value(i).Value(j),
883 Ujp1=myParCont->Value(i).Value(j+1);
884 if (!LinCont->ProjectedCurve().IsNull())
885 P2d = LinCont->ProjectedCurve()->Value((Ujp1+3*Uj)/4);
888 { if (!LinCont->Curve2dOnSurf().IsNull())
889 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+3*Uj)/4);
893 LinCont->D0((Ujp1+3*Uj)/4,PP);
894 P2d = ProjectPoint(PP);
897 UV.SetX(P2d.Coord(1));
898 UV.SetY(P2d.Coord(2));
900 // point milieu precedent
901 if (!LinCont->ProjectedCurve().IsNull())
902 P2d = LinCont->ProjectedCurve()->Value((Ujp1+Uj)/2);
905 { if (!LinCont->Curve2dOnSurf().IsNull())
906 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+Uj)/2);
910 LinCont->D0((Ujp1+Uj)/2,PP);
911 P2d = ProjectPoint(PP);
915 UV.SetX(P2d.Coord(1));
916 UV.SetY(P2d.Coord(2));
918 // point 3/4 precedent
919 if (!LinCont->ProjectedCurve().IsNull())
920 P2d = LinCont->ProjectedCurve()->Value((3*Ujp1+Uj)/4);
923 { if (!LinCont->Curve2dOnSurf().IsNull())
924 P2d = LinCont->Curve2dOnSurf()->Value((3*Ujp1+Uj)/4);
928 LinCont->D0((3*Ujp1+Uj)/4,PP);
929 P2d = ProjectPoint(PP);
933 UV.SetX(P2d.Coord(1));
934 UV.SetY(P2d.Coord(2));
936 // point de contrainte courant
937 if (!LinCont->ProjectedCurve().IsNull())
938 P2d = LinCont->ProjectedCurve()->Value(Ujp1);
941 { if (!LinCont->Curve2dOnSurf().IsNull())
942 P2d = LinCont->Curve2dOnSurf()->Value(Ujp1);
946 LinCont->D0(Ujp1,PP);
947 P2d = ProjectPoint(PP);
951 UV.SetX(P2d.Coord(1));
952 UV.SetY(P2d.Coord(2));
959 //---------------------------------------------------------
960 // fonction : Disc3dContour
961 //---------------------------------------------------------
962 void GeomPlate_BuildPlateSurface::
963 Disc3dContour (const Standard_Integer /*nbp*/,
964 const Standard_Integer iordre,
965 TColgp_SequenceOfXYZ& Seq3d)
968 if (Seq3d.Length()!=4)
969 cout<<"nbp doit etre egal a 4 pour Disc3dContour"<<endl;
970 if (iordre!=0&&iordre!=1)
971 cout<<"iordre incorrect pour Disc3dContour"<<endl;
975 // echantillonnage en "cosinus" + 3 points sur chaque intervalle
976 Standard_Real u1,v1,u2,v2;
977 mySurfInit->Bounds(u1,v1,u2,v2);
978 GeomAdaptor_Surface Surf(mySurfInit);
979 myProj.Initialize(Surf,u1,v1,u2,v2,
980 Surf.UResolution(myTol3d),
981 Surf.VResolution(myTol3d));
982 Standard_Integer NTCurve = myLinCont->Length();
983 Standard_Integer NTPntCont = myPntCont->Length();
990 for( i=1; i<=NTPntCont; i++)
991 if (myPntCont->Value(i)->Order()!=-1)
993 { myPntCont->Value(i)->D0(P3d);
1000 myPntCont->Value(i)->D1(P3d,v1h,v2h);
1009 for(i=1; i<=NTCurve; i++)
1010 if (myLinCont->Value(i)->Order()!=-1)
1012 { Standard_Integer NbPt=myParCont->Value(i).Length();;
1013 // premier point de contrainte (j=0)
1014 // Standard_Integer NbPt=myParCont->Length();
1016 myLinCont->Value(i)->D0(myParCont->Value(i).Value(1),P3d);
1023 myLinCont->Value(i)->D1(myParCont->Value(i).Value(1),P3d,v1h,v2h);
1031 for (Standard_Integer j=2; j<NbPt; j++)
1032 { Standard_Real Uj=myParCont->Value(i).Value(j),
1033 Ujp1=myParCont->Value(i).Value(j+1);
1035 // point 1/4 precedent
1036 myLinCont->Value(i)->D0((Ujp1+3*Uj)/4,P3d);
1041 // point milieu precedent
1042 myLinCont->Value(i)->D0((Ujp1+Uj)/2,P3d);
1047 // point 3/4 precedent
1048 myLinCont->Value(i)->D0((3*Ujp1+Uj)/4,P3d);
1053 // point de contrainte courant
1054 myLinCont->Value(i)->D0(Ujp1,P3d);
1061 // point 1/4 precedent
1062 myLinCont->Value(i)->D1((Ujp1+3*Uj)/4,P3d,v1h,v2h);
1068 // point milieu precedent
1069 myLinCont->Value(i)->D1((Ujp1+Uj)/2,P3d,v1h,v2h);
1075 // point 3/4 precedent
1076 myLinCont->Value(i)->D1((3*Ujp1+Uj)/4,P3d,v1h,v2h);
1082 // point de contrainte courant
1083 myLinCont->Value(i)->D1(Ujp1,P3d,v1h,v2h);
1096 //---------------------------------------------------------
1097 // fonction : IsDone
1098 //---------------------------------------------------------
1099 Standard_Boolean GeomPlate_BuildPlateSurface::IsDone() const
1100 { return myPlate.IsDone();
1105 //---------------------------------------------------------
1106 // fonction : Surface
1107 //---------------------------------------------------------
1108 Handle(GeomPlate_Surface) GeomPlate_BuildPlateSurface::Surface() const
1109 { return myGeomPlateSurface ;
1112 //---------------------------------------------------------
1113 // fonction : SurfInit
1114 //---------------------------------------------------------
1115 Handle(Geom_Surface) GeomPlate_BuildPlateSurface::SurfInit() const
1116 { return mySurfInit ;
1120 //---------------------------------------------------------
1122 //---------------------------------------------------------
1123 Handle(TColStd_HArray1OfInteger) GeomPlate_BuildPlateSurface::Sense() const
1124 { Standard_Integer NTCurve = myLinCont->Length();
1125 Handle(TColStd_HArray1OfInteger) Sens = new TColStd_HArray1OfInteger(1,
1127 for (Standard_Integer i=1; i<=NTCurve; i++)
1128 Sens->SetValue(i,mySense->Value(myInitOrder->Value(i)));
1134 //---------------------------------------------------------
1135 // fonction : Curve2d
1136 //---------------------------------------------------------
1137 Handle(TColGeom2d_HArray1OfCurve) GeomPlate_BuildPlateSurface::Curves2d() const
1138 { Standard_Integer NTCurve = myLinCont->Length();
1139 Handle(TColGeom2d_HArray1OfCurve) C2dfin =
1140 new TColGeom2d_HArray1OfCurve(1,NTCurve);
1142 for (Standard_Integer i=1; i<=NTCurve; i++)
1143 C2dfin->SetValue(i,myLinCont->Value(myInitOrder->Value(i))->Curve2dOnSurf());
1149 //---------------------------------------------------------
1151 //---------------------------------------------------------
1152 Handle(TColStd_HArray1OfInteger) GeomPlate_BuildPlateSurface::Order() const
1153 { Handle(TColStd_HArray1OfInteger) result=
1154 new TColStd_HArray1OfInteger(1,myLinCont->Length());
1155 for (Standard_Integer i=1;i<=myLinCont->Length();i++)
1156 result->SetValue(myInitOrder->Value(i),i);
1161 //---------------------------------------------------------
1162 // fonction : G0Error
1163 //---------------------------------------------------------
1164 Standard_Real GeomPlate_BuildPlateSurface::G0Error() const
1168 //---------------------------------------------------------
1169 // fonction : G1Error
1170 //---------------------------------------------------------
1171 Standard_Real GeomPlate_BuildPlateSurface::G1Error() const
1175 //---------------------------------------------------------
1176 // fonction : G2Error
1177 //---------------------------------------------------------
1178 Standard_Real GeomPlate_BuildPlateSurface::G2Error() const
1182 //=======================================================================
1183 //function : G0Error
1185 //=======================================================================
1187 Standard_Real GeomPlate_BuildPlateSurface::G0Error( const Standard_Integer Index )
1189 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1190 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1191 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1192 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1193 Standard_Real MaxDistance = 0.;
1194 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1195 if (tdistance->Value(i) > MaxDistance)
1196 MaxDistance = tdistance->Value(i);
1200 //=======================================================================
1201 //function : G1Error
1203 //=======================================================================
1205 Standard_Real GeomPlate_BuildPlateSurface::G1Error( const Standard_Integer Index )
1207 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1208 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1209 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1210 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1211 Standard_Real MaxAngle = 0.;
1212 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1213 if (tangle->Value(i) > MaxAngle)
1214 MaxAngle = tangle->Value(i);
1218 //=======================================================================
1219 //function : G2Error
1221 //=======================================================================
1223 Standard_Real GeomPlate_BuildPlateSurface::G2Error( const Standard_Integer Index )
1225 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1226 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1227 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1228 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1229 Standard_Real MaxCurvature = 0.;
1230 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1231 if (tcurvature->Value(i) > MaxCurvature)
1232 MaxCurvature = tcurvature->Value(i);
1233 return MaxCurvature;
1236 Handle(GeomPlate_CurveConstraint) GeomPlate_BuildPlateSurface::CurveConstraint( const Standard_Integer order) const
1238 return myLinCont->Value(order);
1240 Handle(GeomPlate_PointConstraint) GeomPlate_BuildPlateSurface::PointConstraint( const Standard_Integer order) const
1242 return myPntCont->Value(order);
1244 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1245 // =========================================================
1246 // M E T H O D E S P R I V E S
1247 // =========================================================
1248 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1250 //=======================================================================
1251 // function : CourbeJointive
1252 // purpose : Effectue un chainage des courbes pour pouvoir calculer
1253 // la surface d'init avec la methode du flux maxi.
1254 // Retourne vrai si il s'agit d'un contour ferme.
1255 //=======================================================================
1257 Standard_Boolean GeomPlate_BuildPlateSurface::
1258 CourbeJointive(const Standard_Real tolerance)
1259 { Standard_Integer nbf = myLinCont->Length();
1260 Standard_Real Ufinal1,Uinit1,Ufinal2,Uinit2;
1261 mySense = new TColStd_HArray1OfInteger(1,nbf,0);
1262 Standard_Boolean result=Standard_True;
1263 Standard_Integer j=1,i;
1266 while (j <= (myNbBounds-1))
1268 Standard_Integer a=0;
1271 { result = Standard_False;
1275 { if (i > myNbBounds)
1276 { result = Standard_False;
1281 Uinit1=myLinCont->Value(j)->FirstParameter();
1282 Ufinal1=myLinCont->Value(j)->LastParameter();
1283 Uinit2=myLinCont->Value(i)->FirstParameter();
1284 Ufinal2=myLinCont->Value(i)->LastParameter();
1285 if (mySense->Value(j)==1)
1287 myLinCont->Value(j)->D0(Ufinal1,P1);
1288 myLinCont->Value(i)->D0(Uinit2,P2);
1289 if (P1.Distance(P2)<tolerance)
1291 Handle(GeomPlate_CurveConstraint) tampon = myLinCont->Value(j+1);
1292 myLinCont->SetValue(j+1,myLinCont->Value(i));
1293 myLinCont->SetValue(i,tampon);
1294 Standard_Integer Tmp=myInitOrder->Value(j+1);
1295 //Voir fonction TrierTab pour le fonctionnement de myInitOrder
1296 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1297 myInitOrder->SetValue(i,Tmp);
1302 mySense->SetValue(j+1,0);
1306 { myLinCont->Value(i)->D0(Ufinal2,P2);
1308 if (P1.Distance(P2)<tolerance)
1310 Handle(GeomPlate_CurveConstraint) tampon =
1311 myLinCont->Value(j+1);
1312 myLinCont->SetValue(j+1,myLinCont->Value(i));
1313 myLinCont->SetValue(i,tampon);
1314 Standard_Integer Tmp=myInitOrder->Value(j+1);
1315 //Voir fonction TrierTab pour le fonctionnement de myInitOrder
1316 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1317 myInitOrder->SetValue(i,Tmp);
1320 mySense->SetValue(j+1,1);
1328 Uinit1=myLinCont->Value( myNbBounds )->FirstParameter();
1329 Ufinal1=myLinCont->Value( myNbBounds )->LastParameter();
1330 Uinit2=myLinCont->Value(1)->FirstParameter();
1331 Ufinal2=myLinCont->Value(1)->LastParameter();
1332 myLinCont->Value( myNbBounds )->D0(Ufinal1,P1);
1333 myLinCont->Value(1)->D0(Uinit2,P2);
1334 if ((mySense->Value( myNbBounds )==0)
1335 &&(P1.Distance(P2)<tolerance))
1337 return ((Standard_True)&&(result));
1339 myLinCont->Value( myNbBounds )->D0(Uinit1,P1);
1340 if ((mySense->Value( myNbBounds )==1)
1341 &&(P1.Distance(P2)<tolerance))
1343 return ((Standard_True)&&(result));
1345 else return Standard_False;
1349 //-------------------------------------------------------------------------
1350 // fonction : ComputeSurfInit
1351 //-------------------------------------------------------------------------
1352 // Calcul la surface d'init soit par la methode du flux maxi soit par
1353 // la methode du plan d'inertie si le contour n'est pas ferme ou si
1354 // il y a des contraintes ponctuelles
1355 //-------------------------------------------------------------------------
1357 void GeomPlate_BuildPlateSurface::ComputeSurfInit()
1359 Standard_Integer nopt=2, popt=2, Np=1;
1360 Standard_Boolean isHalfSpace = Standard_True;
1361 Standard_Real LinTol = 0.001, AngTol = 0.001; //AngTol = 0.0001; //LinTol = 0.0001
1363 // Option pour le calcul du plan initial
1364 Standard_Integer NTLinCont = myLinCont->Length(), NTPntCont = myPntCont->Length();
1365 // Tableau des permutation pour conserver l'ordre initial voir TrierTab
1366 if (NTLinCont != 0) {
1367 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
1368 for (Standard_Integer i = 1; i <= NTLinCont; i++)
1369 myInitOrder->SetValue( i, i );
1372 Standard_Boolean CourbeJoint = (NTLinCont != 0) && CourbeJointive (myTol3d);
1373 if (CourbeJoint && IsOrderG1())
1376 // Tableau contenant le nuage de point pour le calcul du plan
1377 Standard_Integer NbPoint = 20, Discr = NbPoint/4, pnum = 0;
1378 Handle( TColgp_HArray1OfPnt ) Pts = new TColgp_HArray1OfPnt( 1, (NbPoint+1)*NTLinCont+NTPntCont );
1379 TColgp_SequenceOfVec Vecs, NewVecs;
1380 GeomPlate_SequenceOfAij Aset;
1381 Standard_Real Uinit, Ufinal, Uif;
1383 Standard_Integer i ;
1384 for ( i = 1; i <= NTLinCont; i++)
1386 Standard_Integer Order = myLinCont->Value(i)->Order();
1390 Uinit = myLinCont->Value(i)->FirstParameter();
1391 Ufinal = myLinCont->Value(i)->LastParameter();
1392 Uif = Ufinal - Uinit;
1393 if (mySense->Value(i) == 1)
1399 gp_Vec Vec1, Vec2, Normal;
1400 Standard_Boolean ToReverse = Standard_False;
1401 if (i > 1 && Order >= GeomAbs_G1)
1404 myLinCont->Value(i)->D1( Uinit, P, Vec1, Vec2 );
1405 Normal = Vec1 ^ Vec2;
1406 if (LastVec.IsOpposite( Normal, AngTol ))
1407 ToReverse = Standard_True;
1410 for (Standard_Integer j = 0; j <= NbPoint; j++)
1411 { // Nombre de point par courbe = 20
1412 // Repartition lineaire
1413 Standard_Real Inter = j*Uif/(NbPoint);
1414 if (Order < GeomAbs_G1 || j % Discr != 0)
1415 myLinCont->Value(i)->D0( Uinit+Inter, Pts->ChangeValue(++pnum) );
1418 myLinCont->Value(i)->D1( Uinit+Inter, Pts->ChangeValue(++pnum), Vec1, Vec2 );
1419 Normal = Vec1 ^ Vec2;
1423 Standard_Boolean isNew = Standard_True;
1424 Standard_Integer k ;
1425 for ( k = 1; k <= Vecs.Length(); k++)
1426 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1428 isNew = Standard_False;
1432 for (k = 1; k <= NewVecs.Length(); k++)
1433 if (NewVecs(k).IsEqual( Normal, LinTol, AngTol ))
1435 isNew = Standard_False;
1439 NewVecs.Append( Normal );
1442 if (Order >= GeomAbs_G1)
1444 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1449 } //for (i = 1; i <= NTLinCont; i++)
1453 for (i = 1; i <= NTPntCont; i++)
1455 Standard_Integer Order = myPntCont->Value(i)->Order();
1458 gp_Vec Vec1, Vec2, Normal;
1459 if (Order < GeomAbs_G1)
1460 myPntCont->Value(i)->D0( Pts->ChangeValue(++pnum) );
1463 myPntCont->Value(i)->D1( Pts->ChangeValue(++pnum), Vec1, Vec2 );
1464 Normal = Vec1 ^ Vec2;
1466 Standard_Boolean isNew = Standard_True;
1467 for (Standard_Integer k = 1; k <= Vecs.Length(); k++)
1468 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1470 isNew = Standard_False;
1475 NewVecs.Append( Normal );
1476 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1479 NewVecs(1).Reverse();
1480 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1486 } //for (i = 1; i <= NTPntCont; i++)
1490 Standard_Boolean NullExist = Standard_True;
1493 NullExist = Standard_False;
1494 for (i = 1; i <= Vecs.Length(); i++)
1495 if (Vecs(i).SquareMagnitude() == 0.)
1497 NullExist = Standard_True;
1502 GeomPlate_BuildAveragePlane BAP( Vecs, Pts );
1503 Standard_Real u1,u2,v1,v2;
1504 BAP.MinMaxBox(u1,u2,v1,v2);
1505 // On agrandit le bazar pour les projections
1506 Standard_Real du = u2 - u1;
1507 Standard_Real dv = v2 - v1;
1508 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1509 mySurfInit = new Geom_RectangularTrimmedSurface( BAP.Plane(), u1,u2,v1,v2 );
1511 } //if (isHalfSpace)
1515 cout<<endl<<"Normals are not in half space"<<endl<<endl;
1517 myIsLinear = Standard_False;
1520 } //if (NTLinCont != 0 && (CourbeJoint = CourbeJointive( myTol3d )) && IsOrderG1())
1523 TrierTab( myInitOrder ); // Reordonne le tableau des permutations
1527 if ( NTPntCont != 0)
1528 nopt = 1; //Calcul par la methode du plan d'inertie
1529 else if (!CourbeJoint || NTLinCont != myNbBounds)
1530 {// throw Standard_Failure("Curves are not joined");
1532 cout<<"WARNING : Courbes non jointives a "<<myTol3d<<" pres"<<endl;
1537 Standard_Real LenT=0;
1538 Standard_Integer Npt=0;
1539 Standard_Integer NTPoint=20*NTLinCont;
1540 Standard_Integer i ;
1541 for ( i=1;i<=NTLinCont;i++)
1542 LenT+=myLinCont->Value(i)->Length();
1543 for (i=1;i<=NTLinCont;i++)
1544 { Standard_Integer NbPoint= (Standard_Integer )( NTPoint*(myLinCont->Value(i)->Length())/LenT);
1549 // Tableau contenant le nuage de point pour le calcul du plan
1550 Handle(TColgp_HArray1OfPnt) Pts = new TColgp_HArray1OfPnt(1,20*NTLinCont+NTPntCont);
1551 Standard_Integer NbPoint=20;
1552 Standard_Real Uinit,Ufinal, Uif;
1553 for ( i=1;i<=NTLinCont;i++)
1554 { Uinit=myLinCont->Value(i)->FirstParameter();
1555 Ufinal=myLinCont->Value(i)->LastParameter();
1557 if (mySense->Value(i) == 1)
1561 for (Standard_Integer j=0; j<NbPoint; j++)
1562 { // Nombre de point par courbe = 20
1563 // Repartition lineaire
1564 Standard_Real Inter=j*Uif/(NbPoint);
1566 myLinCont->Value(i)->D0(Uinit+Inter,P);
1567 Pts->SetValue(Np++,P);
1570 for (i=1;i<=NTPntCont;i++)
1572 myPntCont->Value(i)->D0(P);
1573 Pts->SetValue(Np++,P);
1577 GeomPlate_BuildAveragePlane BAP( Pts, NbPoint*myNbBounds, myTol3d/1000, popt, nopt );
1581 cout << "WARNING : GeomPlate : the initial surface is not a plane." << endl;
1586 Standard_Real u1,u2,v1,v2;
1587 BAP.MinMaxBox(u1,u2,v1,v2);
1588 // On agrandit le bazar pour les projections
1589 Standard_Real du = u2 - u1;
1590 Standard_Real dv = v2 - v1;
1591 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1592 mySurfInit = new Geom_RectangularTrimmedSurface(BAP.Plane(),u1,u2,v1,v2);
1595 //Comparing metrics of curves and projected curves
1596 if (NTLinCont != 0 && myIsLinear)
1598 Handle( Geom_Surface ) InitPlane =
1599 (Handle( Geom_RectangularTrimmedSurface )::DownCast(mySurfInit))->BasisSurface();
1601 Standard_Real Ratio = 0., R1 = 2., R2 = 0.6; //R1 = 3, R2 = 0.5;//R1 = 1.4, R2 = 0.8; //R1 = 5., R2 = 0.2;
1602 Handle( GeomAdaptor_HSurface ) hsur =
1603 new GeomAdaptor_HSurface( InitPlane );
1604 Standard_Integer NbPoint = 20;
1606 // gp_Vec DerC, DerCproj, DU, DV;
1611 for (Standard_Integer i = 1; i <= NTLinCont && myIsLinear; i++)
1613 Standard_Real FirstPar = myLinCont->Value(i)->FirstParameter();
1614 Standard_Real LastPar = myLinCont->Value(i)->LastParameter();
1615 Standard_Real Uif = (LastPar - FirstPar)/(NbPoint);
1617 Handle( Adaptor3d_HCurve ) Curve = myLinCont->Value(i)->Curve3d();
1618 ProjLib_CompProjectedCurve Projector( hsur, Curve, myTol3d, myTol3d );
1619 Handle( ProjLib_HCompProjectedCurve ) ProjCurve =
1620 new ProjLib_HCompProjectedCurve();
1621 ProjCurve->Set( Projector );
1622 Adaptor3d_CurveOnSurface AProj(ProjCurve, hsur);
1625 gp_Vec DerC, DerCproj;
1626 for (Standard_Integer j = 1 ; j < NbPoint && myIsLinear; j++)
1628 Standard_Real Inter = FirstPar + j*Uif;
1629 Curve->D1(Inter, P, DerC);
1630 AProj.D1(Inter, P, DerCproj);
1632 Standard_Real A1 = DerC.Magnitude();
1633 Standard_Real A2 = DerCproj.Magnitude();
1640 if (Ratio > R1 || Ratio < R2)
1642 myIsLinear = Standard_False;
1649 cout <<"Metrics are too different :"<< Ratio<<endl;
1651 // myIsLinear = Standard_True; // !!
1652 } //comparing metrics of curves and projected curves
1657 myPlanarSurfInit = mySurfInit;
1661 sprintf(name,"planinit_%d",NbPlan+1);
1662 DrawTrSurf::Set(name, mySurfInit);
1665 Standard_Real u1,v1,u2,v2;
1666 mySurfInit->Bounds(u1,v1,u2,v2);
1667 GeomAdaptor_Surface Surf(mySurfInit);
1668 myTolU = Surf.UResolution(myTol3d);
1669 myTolV = Surf.VResolution(myTol3d);
1670 myProj.Initialize(Surf,u1,v1,u2,v2,
1673 //======================================================================
1674 // Projection des courbes
1675 //======================================================================
1677 for (i = 1; i <= NTLinCont; i++)
1678 if (myLinCont->Value(i)->Curve2dOnSurf().IsNull())
1679 myLinCont->ChangeValue(i)->SetCurve2dOnSurf(ProjectCurve(myLinCont->Value(i)->Curve3d()));
1681 //======================================================================
1682 // Projection des points
1683 //======================================================================
1684 for (i = 1; i<=NTPntCont; i++)
1686 myPntCont->Value(i)->D0(P);
1687 if (!myPntCont->Value(i)->HasPnt2dOnSurf())
1688 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
1691 //======================================================================
1692 // Nbre de point par courbe
1693 //======================================================================
1694 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
1697 //======================================================================
1698 // Gestion des incompatibilites entre courbes
1699 //======================================================================
1700 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
1701 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
1704 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1705 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1706 Intersect(PntInter, PntG1G1);
1709 //====================================================================
1710 // Discretisation des courbes
1711 //====================================================================
1712 Discretise(PntInter, PntG1G1);
1713 //====================================================================
1714 //Preparation des points de contrainte pour plate
1715 //====================================================================
1717 if (myPntCont->Length() != 0)
1719 //====================================================================
1720 //Resolution de la surface
1721 //====================================================================
1722 myPlate.SolveTI(2, ComputeAnisotropie());
1723 if (!myPlate.IsDone())
1726 cout << "WARNING : GeomPlate : abort calcul of Plate." << endl;
1731 myGeomPlateSurface = new GeomPlate_Surface( mySurfInit, myPlate );
1733 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
1737 mySurfInit = App.Surface();
1739 mySurfInitIsGive = Standard_True;
1740 myPlate.Init(); // Reset
1742 for (i=1;i<=NTLinCont;i++)
1744 Handle( Geom2d_Curve ) NullCurve;
1745 NullCurve.Nullify();
1746 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( NullCurve);
1753 sprintf(name,"surfinit_%d",++NbPlan);
1754 DrawTrSurf::Set(name, mySurfInit);
1759 //---------------------------------------------------------
1760 // fonction : Intersect
1761 //---------------------------------------------------------
1762 // Recherche les intersections entre les courbe 2d
1763 // Si intersection et compatible( dans le cas G1-G1)
1764 // enleve le point sur une des deux courbes
1765 //---------------------------------------------------------
1766 void GeomPlate_BuildPlateSurface::
1767 Intersect(Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1768 Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1770 Standard_Integer NTLinCont = myLinCont->Length();
1771 Geom2dInt_GInter Intersection;
1772 Geom2dAdaptor_Curve Ci, Cj;
1773 IntRes2d_IntersectionPoint int2d;
1777 // if (!mySurfInitIsGive)
1778 for (Standard_Integer i=1;i<=NTLinCont;i++)
1780 //Standard_Real NbPnt_i=myLinCont->Value(i)->NbPoints();
1781 // Cherche l'intersection avec chaque courbe y compris elle meme.
1782 Ci.Load(myLinCont->Value(i)->Curve2dOnSurf());
1783 for(Standard_Integer j=i; j<=NTLinCont; j++)
1785 Cj.Load(myLinCont->Value(j)->Curve2dOnSurf());
1787 Intersection.Perform(Ci, myTol2d*10, myTol2d*10);
1789 Intersection.Perform(Ci, Cj, myTol2d*10, myTol2d*10);
1791 if (!Intersection.IsEmpty())
1792 { // il existe une intersection
1793 Standard_Integer nbpt = Intersection.NbPoints();
1794 // nombre de point d'intersection
1795 for (Standard_Integer k = 1; k <= nbpt; k++)
1796 { int2d = Intersection.Point(k);
1797 myLinCont->Value(i)->D0(int2d.ParamOnFirst(),P1);
1798 myLinCont->Value(j)->D0(int2d.ParamOnSecond(),P2);
1802 cout << " Intersection "<< k << " entre " << i
1803 << " &" << j << endl;
1804 cout <<" Distance = "<< P1.Distance(P2) << endl;
1807 if (P1.Distance( P2 ) < myTol3d)
1808 { // L'intersection 2d correspond a des points 3d proches
1809 // On note l'intervalle dans lequel il faudra enlever
1810 // un point pour eviter les doublons ce qui fait une
1811 // erreur dans plate. le point sur la courbe i est enleve
1812 // on conserve celui de la courbe j
1813 // la longueur de l'intervalle est une longueur 2d
1814 // correspondant en 3d a myTol3d
1815 Standard_Real tolint = Ci.Resolution(myTol3d);
1816 Ci.D1(int2d.ParamOnFirst(),P2d, V2d);
1817 Standard_Real aux = V2d.Magnitude();
1821 if (aux > 100*tolint) tolint*=100;
1826 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1827 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1829 if ( (myLinCont->Value(i)->Order()==1)
1830 &&(myLinCont->Value(j)->Order()==1))
1831 { gp_Vec v11,v12,v13,v14,v15,v16,v21,v22,v23,v24,v25,v26;
1832 myLinCont->Value(i)->D2( int2d.ParamOnFirst(), P1, v11, v12, v13, v14, v15 );
1833 myLinCont->Value(j)->D2( int2d.ParamOnSecond(), P2, v21, v22, v23, v24, v25 );
1834 v16=v11^v12;v26=v21^v22;
1835 Standard_Real ant=v16.Angle(v26);
1838 if ((Abs(v16*v15-v16*v25)>(myTol3d/1000))
1839 ||(Abs(ant)>myTol3d/1000))
1840 // Pas compatible ==> on enleve une zone en
1841 // contrainte G1 correspondant
1842 // a une tolerance 3D de 0.01
1843 { Standard_Real coin;
1844 Standard_Real Tol= 100 * myTol3d;
1846 gp_Pnt2d P1temp,P2temp;
1848 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1temp, V1);
1849 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2temp, V2);
1853 if (Abs(Abs(A1)-M_PI)<myTolAng) Tol = 100000 * myTol3d;
1855 if (Affich) cout <<"Angle entre Courbe "<<i<<","<<j
1856 <<" "<<Abs(Abs(A1)-M_PI)<<endl;
1859 coin = Ci.Resolution(Tol);
1860 Standard_Real Par1=int2d.ParamOnFirst()-coin,
1861 Par2=int2d.ParamOnFirst()+coin;
1862 // Stockage de l'intervalle pour la courbe i
1863 PntG1G1->ChangeValue(i).Append(Par1);
1864 PntG1G1->ChangeValue(i).Append(Par2);
1865 coin = Cj.Resolution(Tol);
1866 Par1=int2d.ParamOnSecond()-coin;
1867 Par2=int2d.ParamOnSecond()+coin;
1868 // Stockage de l'intervalle pour la courbe j
1869 PntG1G1->ChangeValue(j).Append(Par1);
1870 PntG1G1->ChangeValue(j).Append(Par2);
1874 if ((myLinCont->Value(i)->Order()==0 && myLinCont->Value(j)->Order()==1) ||
1875 (myLinCont->Value(i)->Order()==1 && myLinCont->Value(j)->Order()==0))
1877 gp_Vec vec, vecU, vecV, N;
1878 if (myLinCont->Value(i)->Order() == 0)
1880 Handle( Adaptor3d_HCurve ) theCurve = myLinCont->Value(i)->Curve3d();
1881 theCurve->D1( int2d.ParamOnFirst(), P1, vec );
1882 myLinCont->Value(j)->D1( int2d.ParamOnSecond(), P2, vecU, vecV );
1886 Handle( Adaptor3d_HCurve ) theCurve = myLinCont->Value(j)->Curve3d();
1887 theCurve->D1( int2d.ParamOnSecond(), P2, vec );
1888 myLinCont->Value(i)->D1( int2d.ParamOnFirst(), P1, vecU, vecV );
1891 Standard_Real Angle = vec.Angle( N );
1892 Angle = Abs( M_PI/2-Angle );
1893 if (Angle > myTolAng/10.) //????????? //if (Abs( scal ) > myTol3d/100)
1894 { // Pas compatible ==> on enleve une zone en
1895 // contrainte G0 et G1 correspondant
1896 // a une tolerance 3D de 0.01
1898 Standard_Real Tol= 100 * myTol3d;
1900 gp_Pnt2d P1temp,P2temp;
1902 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1temp, V1);
1903 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2temp, V2);
1904 A1 = V1.Angle( V2 );
1907 if (Abs(Abs(A1) - M_PI) < myTolAng) Tol = 100000 * myTol3d;
1909 if (Affich) cout <<"Angle entre Courbe "<<i<<","<<j
1910 <<" "<<Abs(Abs(A1)-M_PI)<<endl;
1912 if (myLinCont->Value(i)->Order() == 1)
1914 coin = Ci.Resolution(Tol);
1915 coin *= Angle / myTolAng * 10.;
1917 cout<<endl<<"coin = "<<coin<<endl;
1919 Standard_Real Par1 = int2d.ParamOnFirst() - coin;
1920 Standard_Real Par2 = int2d.ParamOnFirst() + coin;
1921 // Stockage de l'intervalle pour la courbe i
1922 PntG1G1->ChangeValue(i).Append( Par1 );
1923 PntG1G1->ChangeValue(i).Append( Par2 );
1927 coin = Cj.Resolution(Tol);
1928 coin *= Angle / myTolAng * 10.;
1930 cout<<endl<<"coin = "<<coin<<endl;
1932 Standard_Real Par1 = int2d.ParamOnSecond() - coin;
1933 Standard_Real Par2 = int2d.ParamOnSecond() + coin;
1934 // Stockage de l'intervalle pour la courbe j
1935 PntG1G1->ChangeValue(j).Append( Par1 );
1936 PntG1G1->ChangeValue(j).Append( Par2 );
1940 } //if (P1.Distance( P2 ) < myTol3d)
1942 //L'intersection 2d correspond a des points 3d eloigne
1943 // On note l'intervalle dans lequel il faudra enlever
1944 // des points pour eviter les doublons ce qui fait une
1945 // erreur dans plate. le point sur la courbe i est enleve
1946 // on conserve celui de la courbe j.
1947 // la longueur de l'intervalle est une longueur 2d
1948 // correspondant a la distance des points en 3d a myTol3d
1949 Standard_Real tolint, Dist;
1950 Dist = P1.Distance(P2);
1951 tolint = Ci.Resolution(Dist);
1952 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1953 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1956 tolint = Cj.Resolution(Dist);
1957 PntInter->ChangeValue(j).
1958 Append( int2d.ParamOnSecond() - tolint);
1959 PntInter->ChangeValue(j).
1960 Append( int2d.ParamOnSecond() + tolint);
1964 cout<<"Attention: Deux points 3d ont la meme projection dist="
1970 Handle(Draw_Marker3D) mark = new (Draw_Marker3D)(P1, Draw_X, Draw_vert);
1972 sprintf(name,"mark_%d",++NbMark);
1973 Draw::Set(name, mark);
1983 //---------------------------------------------------------
1984 // fonction : Discretise
1985 //---------------------------------------------------------
1986 // Discretise les courbes selon le parametre de celle-ci
1987 // le tableau des sequences Parcont contiendera tous les
1988 // parametres des points sur les courbes
1989 // Le champ myPlateCont contiendera les parametre des points envoye a plate
1990 // il excluera les points en double et les zones imcompatibles.
1991 // La premiere partie correspond a la verfication de la compatibilite
1992 // et a la supprssion des points en double.
1993 //---------------------------------------------------------
1994 void GeomPlate_BuildPlateSurface::
1995 Discretise(const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1996 const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1998 Standard_Integer NTLinCont = myLinCont->Length();
1999 Standard_Boolean ACR;
2000 Handle(Geom2d_Curve) C2d;
2001 Geom2dAdaptor_Curve AC2d;
2002 // Handle(Adaptor_HCurve2d) HC2d;
2003 Handle(Law_Interpol) acrlaw = new (Law_Interpol) ();
2004 myPlateCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
2005 myParCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
2008 //===========================================================================
2009 // Construction du tableau contenant les parametres des points de contrainte
2010 //===========================================================================
2011 Standard_Real Uinit, Ufinal, Length2d=0, Inter;
2012 Standard_Real CurLength;
2013 Standard_Integer NbPnt_i, NbPtInter, NbPtG1G1;
2014 Handle(GeomPlate_CurveConstraint) LinCont;
2016 for (Standard_Integer i=1;i<=NTLinCont;i++) {
2017 LinCont = myLinCont->Value(i);
2018 Uinit=LinCont->FirstParameter();
2019 Ufinal=LinCont->LastParameter();
2020 // HC2d=LinCont->ProjectedCurve();
2021 // if(HC2d.IsNull())
2022 // ACR = (!HC2d.IsNull() || !C2d.IsNull());
2023 C2d= LinCont->Curve2dOnSurf();
2024 ACR = (!C2d.IsNull());
2026 // On Construit une loi proche de l'abscisse curviligne
2027 if(!C2d.IsNull()) AC2d.Load(C2d);
2028 // AC2d.Load(LinCont->Curve2dOnSurf());
2029 Standard_Integer ii, Nbint = 20;
2031 TColgp_Array1OfPnt2d tabP2d(1, Nbint+1);
2032 tabP2d(1).SetY(Uinit);
2034 tabP2d(Nbint+1).SetY(Ufinal);
2035 /* if (!HC2d.IsNull())
2037 Length2d = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, Ufinal);
2039 Length2d = GCPnts_AbscissaPoint::Length(AC2d, Uinit, Ufinal);
2041 tabP2d(Nbint+1).SetX(Length2d);
2042 for (ii = 2; ii<= Nbint; ii++) {
2043 U = Uinit + (Ufinal-Uinit)*((1-Cos((ii-1)*M_PI/(Nbint)))/2);
2045 /* if (!HC2d.IsNull()) {
2046 Standard_Real L = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, U);
2050 tabP2d(ii).SetX(GCPnts_AbscissaPoint::Length(AC2d, Uinit, U));
2052 acrlaw->Set(tabP2d);
2055 NbPnt_i = (Standard_Integer )( LinCont->NbPoints());
2056 NbPtInter= PntInter->Value(i).Length();
2057 NbPtG1G1= PntG1G1->Value(i).Length();
2061 cout << "Courbe : " << i << endl;
2062 cout << " NbPnt, NbPtInter, NbPtG1G1 :" << NbPnt_i << ", "
2063 << NbPtInter << ", " << NbPtG1G1 << endl;
2066 for (Standard_Integer j=1; j<=NbPnt_i; j++)
2068 // repartition des points en cosinus selon l'ACR 2d
2069 // Afin d'eviter les points d'acumulation dans le 2d
2070 //Inter=Uinit+(Uif)*((-cos(M_PI*((j-1)/(NbPnt_i-1)))+1)/2);
2072 Inter=Ufinal;//pour parer au bug sur sun
2074 CurLength = Length2d*(1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2;
2075 Inter = acrlaw->Value(CurLength);
2078 Inter=Uinit+(Ufinal-Uinit)*((1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2);
2080 myParCont->ChangeValue(i).Append(Inter);// on ajoute le point
2083 for(Standard_Integer l=1;l<=NbPtInter;l+=2)
2085 //on cherche si le point Inter est dans l'intervalle
2086 //PntInter[i] PntInter[i+1]
2087 //auquelle cas il ne faudrait pas le stocker (pb de doublons)
2088 if ((Inter>PntInter->Value(i).Value(l))
2089 &&(Inter<PntInter->Value(i).Value(l+1)))
2092 // pour sortir de la boucle sans stocker le point
2096 if (l+1>=NbPtInter) {
2097 // on a parcouru tout le tableau : Le point
2098 // n'appartient pas a un interval point commun
2101 // est qu'il existe un intervalle incompatible
2102 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2104 if ((Inter>PntG1G1->Value(i).Value(k))
2105 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2107 k=NbPtG1G1+2; // pour sortir de la boucle
2108 // Ajouter les points de contrainte G0
2112 AC2d.D0(Inter, P2d);
2113 LinCont->D0(Inter,P3d);
2114 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2115 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2116 -PP.Coord(2)+P3d.Coord(2),
2117 -PP.Coord(3)+P3d.Coord(3));
2118 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2121 else // le point n'appartient pas a un interval G1
2125 myPlateCont->ChangeValue(i).Append(Inter);
2126 // on ajoute le point
2133 myPlateCont->ChangeValue(i).Append(Inter);
2134 // on ajoute le point
2142 if (NbPtG1G1!=0) // est qu'il existe un intervalle incompatible
2144 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2146 if ((Inter>PntG1G1->Value(i).Value(k))
2147 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2149 k=NbPtG1G1+2; // pour sortir de la boucle
2150 // Ajouter les points de contrainte G0
2154 AC2d.D0(Inter, P2d);
2155 LinCont->D0(Inter,P3d);
2156 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2157 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2158 -PP.Coord(2)+P3d.Coord(2),
2159 -PP.Coord(3)+P3d.Coord(3));
2160 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2164 else // le point n'appartient pas a un intervalle G1
2168 myPlateCont->ChangeValue(i).Append(Inter);
2169 // on ajoute le point
2176 if ( ( (!mySurfInitIsGive)
2177 &&(Geom2dAdaptor_Curve(LinCont->Curve2dOnSurf()).GetType()!=GeomAbs_Circle))
2178 || ( (j>1) &&(j<NbPnt_i))) //on enleve les extremites
2179 myPlateCont->ChangeValue(i).Append(Inter);// on ajoute le point
2185 //---------------------------------------------------------
2186 // fonction : CalculNbPtsInit
2187 //---------------------------------------------------------
2188 // Calcul du nombre de points par courbe en fonction de la longueur
2189 // pour la premiere iteration
2190 //---------------------------------------------------------
2191 void GeomPlate_BuildPlateSurface::CalculNbPtsInit ()
2193 Standard_Real LenT=0;
2194 Standard_Integer NTLinCont=myLinCont->Length();
2195 Standard_Integer NTPoint=(Standard_Integer )( myNbPtsOnCur*NTLinCont);
2196 Standard_Integer i ;
2198 for ( i=1;i<=NTLinCont;i++)
2199 LenT+=myLinCont->Value(i)->Length();
2200 for ( i=1;i<=NTLinCont;i++)
2201 { Standard_Integer Cont=myLinCont->Value(i)->Order();
2203 { case 0 : // Cas G0 *1.2
2204 myLinCont->ChangeValue(i)->SetNbPoints(
2205 Standard_Integer(1.2*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2207 case 1 : // Cas G1 *1
2208 myLinCont->ChangeValue(i)->SetNbPoints(
2209 Standard_Integer(NTPoint*(myLinCont->Value(i)->Length())/LenT));
2211 case 2 : // Cas G2 *0.7
2212 myLinCont->ChangeValue(i)->SetNbPoints(
2213 Standard_Integer(0.7*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2216 if (myLinCont->Value(i)->NbPoints()<3)
2217 myLinCont->ChangeValue(i)->SetNbPoints(3);
2220 //---------------------------------------------------------
2221 // fonction : LoadCurve
2222 //---------------------------------------------------------
2223 // A partir du tableau myParCont on charge tous les points notes dans plate
2224 //---------------------------------------------------------
2225 void GeomPlate_BuildPlateSurface::LoadCurve(const Standard_Integer NbBoucle,
2226 const Standard_Integer OrderMax )
2230 Standard_Integer NTLinCont=myLinCont->Length(), i, j;
2231 Standard_Integer Tang, Nt;
2234 for (i=1; i<=NTLinCont; i++){
2235 Handle(GeomPlate_CurveConstraint) CC = myLinCont->Value(i);
2236 if (CC ->Order()!=-1) {
2237 Tang = Min(CC->Order(), OrderMax);
2238 Nt = myPlateCont->Value(i).Length();
2240 for (j=1; j<=Nt; j++) {// Chargement des points G0 sur les frontieres
2241 CC ->D0(myPlateCont->Value(i).Value(j),P3d);
2242 if (!CC->ProjectedCurve().IsNull())
2243 P2d = CC->ProjectedCurve()->Value(myPlateCont->Value(i).Value(j));
2246 if (!CC->Curve2dOnSurf().IsNull())
2247 P2d = CC->Curve2dOnSurf()->Value(myPlateCont->Value(i).Value(j));
2249 P2d = ProjectPoint(P3d);
2251 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2252 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2253 -PP.Coord(2)+P3d.Coord(2),
2254 -PP.Coord(3)+P3d.Coord(3));
2255 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2258 // Chargement des points G1
2259 if (Tang==1) { // ==1
2261 CC->D1( myPlateCont->Value(i).Value(j), PP, V1, V2 );
2262 mySurfInit->D1( P2d.Coord(1), P2d.Coord(2), PP, V3, V4 );
2264 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2265 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2268 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2271 else if (NbBoucle == 1)
2273 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2274 myPlate.Load( FreeGCC );
2277 gp_Vec DU, DV, Normal, DerPlateU, DerPlateV;
2280 //Normal.Normalize();
2281 Standard_Real norm = Normal.Magnitude();
2282 if (norm > 1.e-12) Normal /= norm;
2283 DerPlateU = myPrevPlate.EvaluateDerivative( P2d.XY(), 1, 0 );
2284 DerPlateV = myPrevPlate.EvaluateDerivative( P2d.XY(), 0, 1 );
2286 DU.SetLinearForm(-(V3 + DerPlateU).Dot(Normal), Normal, DerPlateU);
2287 DV.SetLinearForm(-(V4 + DerPlateV).Dot(Normal), Normal, DerPlateV);
2288 Plate_PinpointConstraint PinU( P2d.XY(), DU.XYZ(), 1, 0 );
2289 Plate_PinpointConstraint PinV( P2d.XY(), DV.XYZ(), 0, 1 );
2290 myPlate.Load( PinU );
2291 myPlate.Load( PinV );
2294 // Chargement des points G2
2296 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2297 CC->D2(myPlateCont->Value(i).Value(j),
2299 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2301 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2302 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2303 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2304 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2307 Plate_GtoCConstraint GCC(P2d.XY(),D1init,D1final,D2init,D2final);
2310 // else // Good but too expansive
2312 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(),
2313 // D1init, D1final, D2init, D2final );
2314 // myPlate.Load( FreeGCC );
2324 //---------------------------------------------------------
2325 //fonction : LoadPoint
2326 //---------------------------------------------------------
2327 //void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer NbBoucle,
2328 void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer ,
2329 const Standard_Integer OrderMax)
2333 Standard_Integer NTPntCont=myPntCont->Length();
2334 Standard_Integer Tang, i;
2335 // gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2337 // Chargement des points de contraintes ponctuel
2338 for (i=1;i<=NTPntCont;i++) {
2339 myPntCont->Value(i)->D0(P3d);
2340 P2d = myPntCont->Value(i)->Pnt2dOnSurf();
2341 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2342 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2343 -PP.Coord(2)+P3d.Coord(2),
2344 -PP.Coord(3)+P3d.Coord(3));
2345 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2347 Tang = Min(myPntCont->Value(i)->Order(), OrderMax);
2348 if (Tang==1) {// ==1
2350 myPntCont->Value(i)->D1(PP,V1,V2);
2351 mySurfInit->D1(P2d.Coord(1),P2d.Coord(2),PP,V3,V4);
2352 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2353 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2356 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2357 myPlate.Load( GCC );
2361 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2362 myPlate.Load( FreeGCC );
2365 // Chargement des points G2 GeomPlate_PlateG0Criterion
2367 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2368 myPntCont->Value(i)->D2(PP,V1,V2,V5,V6,V7);
2369 // gp_Vec Tv2 = V1^V2;
2370 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2371 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2372 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2373 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2374 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2377 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final, D2init, D2final );
2378 myPlate.Load( GCC );
2380 // else // Good but too expansive
2382 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final, D2init//, D2final );
2383 // myPlate.Load( FreeGCC );
2389 //---------------------------------------------------------
2390 //fonction : VerifSurface
2391 //---------------------------------------------------------
2392 Standard_Boolean GeomPlate_BuildPlateSurface::
2393 VerifSurface(const Standard_Integer NbBoucle)
2395 //======================================================================
2396 // Calcul des erreurs
2397 //======================================================================
2398 Standard_Integer NTLinCont=myLinCont->Length();
2399 Standard_Boolean Result=Standard_True;
2401 // variable pour les calculs d erreur
2402 myG0Error=0,myG1Error =0, myG2Error=0;
2404 for (Standard_Integer i=1;i<=NTLinCont;i++) {
2405 Handle(GeomPlate_CurveConstraint) LinCont;
2406 LinCont = myLinCont->Value(i);
2407 if (LinCont->Order()!=-1) {
2408 Standard_Integer NbPts_i = myParCont->Value(i).Length();
2411 Handle(TColStd_HArray1OfReal) tdist =
2412 new TColStd_HArray1OfReal(1,NbPts_i-1);
2413 Handle(TColStd_HArray1OfReal) tang =
2414 new TColStd_HArray1OfReal(1,NbPts_i-1);
2415 Handle(TColStd_HArray1OfReal) tcourb =
2416 new TColStd_HArray1OfReal(1,NbPts_i-1);
2418 EcartContraintesMil (i,tdist,tang,tcourb);
2420 Standard_Real diffDistMax=0,SdiffDist=0;
2421 Standard_Real diffAngMax=0,SdiffAng=0;
2422 Standard_Integer NdiffDist=0,NdiffAng=0;
2425 for (Standard_Integer j=1;j<NbPts_i;j++)
2426 { if (tdist->Value(j)>myG0Error)
2427 myG0Error=tdist->Value(j);
2428 if (tang->Value(j)>myG1Error)
2429 myG1Error=tang->Value(j);
2430 if (tcourb->Value(j)>myG2Error)
2431 myG2Error=tcourb->Value(j);
2433 if (myParCont->Value(i).Length()>3)
2434 U=(myParCont->Value(i).Value(j)+myParCont->Value(i).Value(j+1))/2;
2436 U=LinCont->FirstParameter()+
2437 ( LinCont->LastParameter()-LinCont->FirstParameter())*(j-1)/(NbPts_i-2);
2438 Standard_Real diffDist=tdist->Value(j)-LinCont->G0Criterion(U),diffAng;
2439 if (LinCont->Order()>0)
2440 diffAng=tang->Value(j)-LinCont->G1Criterion(U);
2442 // recherche de la variation de l'erreur maxi et calcul de la moyenne
2444 diffDist = diffDist/LinCont->G0Criterion(U);
2445 if (diffDist>diffDistMax)
2446 diffDistMax = diffDist;
2447 SdiffDist+=diffDist;
2450 if ((Affich) && (NbBoucle == myNbIter)) {
2454 Handle(Draw_Marker3D) mark =
2455 new (Draw_Marker3D)(P, Draw_X, Draw_orange);
2457 sprintf(name,"mark_%d",++NbMark);
2458 Draw::Set(name, mark);
2459 if (!LinCont->ProjectedCurve().IsNull())
2460 P2d = LinCont->ProjectedCurve()->Value(U);
2462 { if (!LinCont->Curve2dOnSurf().IsNull())
2463 P2d = LinCont->Curve2dOnSurf()->Value(U);
2465 P2d = ProjectPoint(P);
2467 sprintf(name,"mark2d_%d",++NbMark);
2468 Handle(Draw_Marker2D) mark2d =
2469 new (Draw_Marker2D)(P2d, Draw_X, Draw_orange);
2470 Draw::Set(name, mark2d);
2475 if ((diffAng>0)&&(LinCont->Order()==1)) {
2476 diffAng=diffAng/myLinCont->Value(i)->G1Criterion(U);
2477 if (diffAng>diffAngMax)
2478 diffAngMax = diffAng;
2482 if ((Affich) && (NbBoucle == myNbIter)) {
2485 Handle(Draw_Marker3D) mark =
2486 new Draw_Marker3D(P, Draw_X, Draw_or);
2488 sprintf(name,"mark_%d",++NbMark);
2489 Draw::Set(name, mark);
2495 if (NdiffDist>0) {// au moins un point n'est pas acceptable en G0
2497 if(LinCont->Order()== 0)
2498 Coef = 0.6*Log(diffDistMax+7.4);
2499 //7.4 correspond au calcul du coef mini = 1.2 donc e^1.2/0.6
2501 Coef = Log(diffDistMax+3.3);
2502 //3.3 correspond au calcul du coef mini = 1.2 donc e^1.2
2505 //experimentalement apres le coef devient mauvais pour les cas L
2506 if ((NbBoucle>1)&&(diffDistMax>2))
2510 if (LinCont->NbPoints()>=Floor(LinCont->NbPoints()*Coef))
2511 Coef=2;// pour assurer une augmentation du nombre de points
2513 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints() * Coef));
2514 Result=Standard_False;
2517 if (NdiffAng>0) // au moins 1 points ne sont pas accepable en G1
2518 { Standard_Real Coef=1.5;
2519 if ((LinCont->NbPoints()+1)>=Floor(LinCont->NbPoints()*Coef))
2522 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints()*Coef )) ;
2523 Result=Standard_False;
2529 if (myFree && NbBoucle == 1)
2530 myPrevPlate = myPlate;
2538 //---------------------------------------------------------
2539 //fonction : VerifPoint
2540 //---------------------------------------------------------
2541 void GeomPlate_BuildPlateSurface::
2542 VerifPoints (Standard_Real& Dist,
2544 Standard_Real& Curv) const
2545 { Standard_Integer NTPntCont=myPntCont->Length();
2548 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
2549 Ang=0;Dist=0,Curv=0;
2550 Handle(GeomPlate_PointConstraint) PntCont;
2551 for (Standard_Integer i=1;i<=NTPntCont;i++) {
2552 PntCont = myPntCont->Value(i);
2553 switch (PntCont->Order())
2555 P2d = PntCont->Pnt2dOnSurf();
2557 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
2558 Dist = Pf.Distance(Pi);
2561 PntCont->D1(Pi, v1i, v2i);
2562 P2d = PntCont->Pnt2dOnSurf();
2563 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
2564 Dist = Pf.Distance(Pi);
2565 v3i = v1i^v2i; v3f=v1f^v2f;
2571 Handle(Geom_Surface) Splate (myGeomPlateSurface);
2572 LocalAnalysis_SurfaceContinuity CG2;
2573 P2d = PntCont->Pnt2dOnSurf();
2574 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
2576 CG2.ComputeAnalysis(Prop, PntCont->LPropSurf(),GeomAbs_G2);
2579 Curv=CG2.G2CurvatureGap();
2585 Standard_Real GeomPlate_BuildPlateSurface::ComputeAnisotropie() const
2595 Standard_Boolean GeomPlate_BuildPlateSurface::IsOrderG1() const
2597 Standard_Boolean result = Standard_True;
2598 for (Standard_Integer i = 1; i <= myLinCont->Length(); i++)
2599 if (myLinCont->Value(i)->Order() < 1)
2601 result = Standard_False;