0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / TPrsStd / TPrsStd_ConstraintTools.cxx
1 // File:        TPrsStd_ConstraintTools.cxx
2 // Language:    C++
3 // Version:     Euclid Designer 2.0
4 // Purpose:     Update AIS object from a TDataXtd_Constraint.
5 // Modified     Mon 30 10:15:43 1998 by SZY
6 //              <szy@philipox.nnov.matra-dtv.fr>
7
8
9 #include <TPrsStd_ConstraintTools.ixx>
10
11 #include <stdio.h>
12 #include <UnitsAPI.hxx>
13 #include <TCollection_ExtendedString.hxx>
14
15 #include <TNaming_Tool.hxx>
16 #include <TNaming_Iterator.hxx>
17 #include <TNaming_NamedShape.hxx>
18 #include <TDF_Label.hxx>
19 #include <TDataStd_Real.hxx>
20 #include <TDataStd_Name.hxx>
21 #include <TDataXtd_Geometry.hxx>
22 #include <TDF_Reference.hxx>
23
24
25 #include <AIS_OffsetDimension.hxx>
26 #include <AIS_LengthDimension.hxx>
27 #include <AIS_ParallelRelation.hxx>
28 #include <AIS_TangentRelation.hxx>
29 #include <AIS_IdenticRelation.hxx>
30 #include <AIS_AngleDimension.hxx>
31 #include <AIS_RadiusDimension.hxx>
32 #include <AIS_DiameterDimension.hxx>
33 #include <AIS_FixRelation.hxx>
34 #include <AIS_PerpendicularRelation.hxx>
35 #include <AIS_ConcentricRelation.hxx>
36 #include <AIS_SymmetricRelation.hxx>
37 #include <AIS_MidPointRelation.hxx>
38 #include <AIS_InteractiveContext.hxx>
39 #include <AIS_Drawer.hxx>
40 #include <AIS_EqualRadiusRelation.hxx>
41 #include <AIS_EqualDistanceRelation.hxx>
42 #include <AIS_MinRadiusDimension.hxx> 
43 #include <AIS_MaxRadiusDimension.hxx>
44
45 #include <TopoDS.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Vertex.hxx>
50 #include <TopExp.hxx>
51 #include <TopExp_Explorer.hxx>
52
53 #include <BRep_Tool.hxx>
54 #include <BRep_Builder.hxx>
55 #include <BRepBuilderAPI_MakeFace.hxx>
56 #include <BRepAdaptor_Curve.hxx>
57 #include <BRepAdaptor_Surface.hxx>
58
59 #include <GeomAbs_SurfaceType.hxx>
60 #include <Geom_Geometry.hxx>
61 #include <Geom_Line.hxx>
62 #include <Geom_Plane.hxx>
63 #include <Geom_CartesianPoint.hxx>
64 #include <Geom_Circle.hxx>
65 #include <gp_Pln.hxx>
66 #include <gp_Dir.hxx>
67 #include <gp_Ax1.hxx>
68 #include <gp_Lin.hxx>
69 #include <gp_Pnt.hxx>
70 #include <gp_Cylinder.hxx>
71 #include <gp_Cone.hxx>
72 #include <gp_Torus.hxx>
73 #include <GC_MakePlane.hxx> 
74
75 #include <Precision.hxx>
76 #include <IntAna_QuadQuadGeo.hxx>
77
78 #include <Standard_ProgramError.hxx>
79 #include <Standard_ErrorHandler.hxx>
80
81 #include <TopTools_IndexedMapOfShape.hxx>
82
83 #define BUC60846
84
85 static Standard_Boolean CheckShapesPair(const TopoDS_Shape& , const TopoDS_Shape& ); //ota
86
87 //=======================================================================
88 //function : static NullifyAIS
89 //purpose  : 
90 //=======================================================================
91 static void NullifyAIS ( Handle(AIS_InteractiveObject)& anais)
92 {
93   if (anais.IsNull())  return;
94   anais.Nullify();
95 }
96
97
98
99 //=======================================================================
100 //function : static FindExternalShape
101 //purpose  : 
102 //=======================================================================
103 static void FindExternalShape(const Handle(TDataXtd_Constraint)& aConst,
104                               Standard_Integer& extShape)
105 {
106   extShape = 0;
107     const TDF_Label& L =  aConst->Label();
108     if (!aConst->GetGeometry(1)->Label().IsDescendant(L)) extShape = 1;    
109     else if (!aConst->GetGeometry(2)->Label().IsDescendant(L)) extShape = 2;
110 }
111
112 //=======================================================================
113 //function : static GetGoodShape for planar constraint
114 //purpose  : 
115 //=======================================================================
116 static void  GetGoodShape(TopoDS_Shape& shape)
117 {
118   switch (shape.ShapeType()) {
119   case TopAbs_EDGE:
120   case TopAbs_VERTEX: { return; }
121   default:
122     {
123       TopExp_Explorer EXP(shape,TopAbs_EDGE);
124       if (EXP.More()) {
125         shape = EXP.Current();
126         return;
127       }
128       else {
129         EXP.Init(shape,TopAbs_VERTEX);
130         if (EXP.More()) shape = EXP.Current();
131       }
132     }
133   }
134 }
135
136 // Pour le cas ou S est un compound
137 static Standard_Boolean IsFace (const TopoDS_Shape& S)
138 {
139   Standard_Boolean  findface = Standard_False;
140   TopExp_Explorer EXP (S,TopAbs_FACE);
141   if (EXP.More()) findface = Standard_True;
142   return  findface;
143 }
144
145 static TopoDS_Face  GetFace (const TopoDS_Shape& S)
146 {
147   TopoDS_Face F;
148   TopExp_Explorer EXP (S,TopAbs_FACE);
149   if (EXP.More())  F = TopoDS::Face (EXP.Current());
150   return  F;
151 }
152
153 static TopoDS_Edge  GetEdge (const TopoDS_Shape& S)
154 {
155   TopoDS_Edge E;
156   TopExp_Explorer EXP (S, TopAbs_EDGE);
157   if (EXP.More()) E = TopoDS::Edge (EXP.Current());
158   return  E;
159 }
160
161
162
163 //=======================================================================
164 //Function : ComputeAndTextValue
165 //purpose  : 
166 //=======================================================================
167 void TPrsStd_ConstraintTools::ComputeTextAndValue(const Handle(TDataXtd_Constraint)& aConst,
168                                                  Standard_Real&                val,
169                                                  TCollection_ExtendedString&   txt,
170                                                  const Standard_Boolean  anIsAngle  )
171 {
172   Standard_Real outvalue;
173   const Handle(TDataStd_Real)& VAL = aConst->GetValue();
174   val      = VAL->Get();
175   if(anIsAngle){
176     outvalue = UnitsAPI::CurrentFromLS(Abs(val),"PLANE ANGLE");
177   }
178   else {
179     outvalue = UnitsAPI::CurrentFromLS(val,"LENGTH");
180   }
181   char res[1000];
182   sprintf(res,"%g",outvalue);
183   txt = TCollection_ExtendedString(res);
184   
185   if (VAL->IsCaptured()) {
186     Handle(TDF_Reference) ref;
187     VAL->Label().FindAttribute(TDF_Reference::GetID(),ref);
188     Handle(TDataStd_Name) name;
189     const TDF_Label& L = ref->Get();
190     if (ref->Get().FindAttribute(TDataStd_Name::GetID(),name)) {
191       TCollection_ExtendedString fullname;
192       Handle(TDataStd_Name) Fathername;
193       if (L.Father().FindAttribute(TDataStd_Name::GetID(),Fathername)) {
194         fullname = Fathername->Get() + TCollection_ExtendedString(".") + name->Get();
195       }
196       else fullname = name->Get();
197       txt = fullname + TCollection_ExtendedString("=") + txt;
198     }
199   }
200 }
201
202
203 //=======================================================================
204 //function : UpdateOnlyValue
205 //purpose  : 
206 //=======================================================================
207
208 void TPrsStd_ConstraintTools::UpdateOnlyValue(const Handle(TDataXtd_Constraint)& aConst, 
209                                      const Handle(AIS_InteractiveObject)& anAIS)
210 {
211   if (anAIS.IsNull()) return; 
212   if (!aConst->IsDimension()) return; 
213   Standard_Real val;
214   TCollection_ExtendedString txt;
215   TPrsStd_ConstraintTools:: ComputeTextAndValue(aConst,val,txt,aConst->GetType() == TDataXtd_ANGLE);
216   Handle(AIS_Relation) rel = Handle(AIS_Relation)::DownCast(anAIS);
217   if (!rel.IsNull()) rel->SetText(txt); 
218 }
219
220
221 //=======================================================================
222 //function : ComputeDistance
223 //purpose  : Build an AIS_LengtDimension.
224 //=======================================================================
225 void TPrsStd_ConstraintTools::ComputeDistance (const Handle(TDataXtd_Constraint)& aConst,
226                                               Handle(AIS_InteractiveObject)& anAIS) 
227 {
228   Standard_Integer nbgeom = aConst->NbGeometries();
229   if (nbgeom < 2) {
230 #ifdef DEB
231     cout <<  "TPrsStd_ConstraintTools::ComputeDistance: at least 2 geometries are needed" << endl;
232 #endif
233     NullifyAIS(anAIS);
234     return;
235   }
236   TopoDS_Shape shape1,shape2,shape3 ;
237   Handle(Geom_Geometry) ageom3;
238   Standard_Boolean is_planar(aConst->IsPlanar()),is_directed(Standard_False);
239   AIS_TypeOfDist typedist = AIS_TOD_Unknown;
240
241   // Get shapes and geometry
242   if (is_planar) {
243     if (nbgeom == 2)
244       GetShapesAndGeom (aConst,shape1,shape2,ageom3);
245     else
246       GetShapesAndGeom (aConst,shape1,shape2,shape3,ageom3);
247   }
248   else
249     GetTwoShapes (aConst,shape1,shape2);    
250
251   if (shape1.IsNull() || shape2.IsNull()) {
252 #ifdef DEB
253     cout << "TPrsStd_ConstraintTools::ComputeDistance : null shape" << endl;
254 #endif
255     NullifyAIS(anAIS);
256     return;
257   }
258
259   Handle(Geom_Plane) aplane;
260   if (is_planar) {
261     if (nbgeom != 2) {
262       is_directed = !shape3.IsNull();
263       if (!is_directed)  {
264 #ifdef DEB
265         cout << "TPrsStd_ConstraintTools::ComputeDistance : null shape" << endl;
266 #endif
267         NullifyAIS(anAIS);
268         return;
269       }
270     }
271
272     GetGoodShape (shape1);
273     GetGoodShape (shape2);
274
275     aplane = Handle(Geom_Plane)::DownCast(ageom3);
276     if (aplane.IsNull()) {
277 #ifdef DEB
278       cout << "TPrsStd_ConstraintTools::ComputeDistance : null plane" << endl;
279 #endif
280       NullifyAIS(anAIS);
281       return;
282     }
283     
284     if (is_directed) {
285       GetGoodShape(shape3);
286       const TopoDS_Edge& E = TopoDS::Edge(shape3);
287       BRepAdaptor_Curve CURVE(E);
288       Handle_Geom_Geometry aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
289       gp_Dir Dir = ((Handle(Geom_Line)&) aGeomGeometry)->Lin().Direction();
290       gp_Dir xdir(aplane->Pln().Position().XDirection());
291       if (Dir.IsParallel(xdir,Precision::Confusion()))
292         typedist = AIS_TOD_Horizontal;
293       else
294         typedist = AIS_TOD_Vertical;
295     }
296   }
297
298   Standard_Real val1;
299   TCollection_ExtendedString txt;
300   ComputeTextAndValue(aConst,val1,txt,Standard_False);
301   
302   //  Arguments de l'AIS
303   Standard_Boolean isface = IsFace(shape1) && IsFace(shape2);
304   Standard_Boolean isedgeface = (shape1.ShapeType () == TopAbs_FACE && 
305                                  shape2.ShapeType () == TopAbs_EDGE);
306   Standard_Boolean is2vertices =(shape1.ShapeType () == TopAbs_VERTEX &&                 //addition 1
307                                  shape2.ShapeType () == TopAbs_VERTEX);
308   if (!isface && !is_planar && !is2vertices)  {
309     // Recherche arguments pouvant convenir
310     if (shape1.ShapeType() == shape2.ShapeType())  {
311       TopoDS_Vertex  v1,v2,v3,v4;
312       if (shape1.ShapeType() == TopAbs_EDGE)  {
313         TopExp::Vertices (TopoDS::Edge(shape1),v1,v2);
314         TopExp::Vertices (TopoDS::Edge(shape2),v3,v4);
315       }
316       else
317       if (shape1.ShapeType() == TopAbs_WIRE)  {
318         TopExp::Vertices (TopoDS::Wire(shape1),v1,v2);
319         TopExp::Vertices (TopoDS::Wire(shape2),v3,v4);
320       }
321       shape1 = v1;
322       gp_Pnt P1 = BRep_Tool::Pnt(v1);
323       gp_Pnt P2 = BRep_Tool::Pnt(v3), P3 = BRep_Tool::Pnt(v4);
324       if (P1.Distance(P2) < P1.Distance(P3))  {
325         shape2 = v3;
326         gp_Ax2 ax2 (P1, gp_Dir (P2.XYZ() - P1.XYZ()));
327         aplane = new Geom_Plane (P1,ax2.XDirection());
328       }
329       else {
330         shape2 = v4;
331         gp_Ax2 ax2 (P1, gp_Dir (P3.XYZ() - P1.XYZ()));
332         aplane = new Geom_Plane (P1,ax2.XDirection());
333       }
334     }
335     else  {
336       if (!isedgeface) {
337         NullifyAIS(anAIS);
338         return;
339       }
340     }
341   }
342
343   //  Update de l'AIS
344   Handle(AIS_LengthDimension) ais;
345   Standard_Boolean SaveDrw = Standard_False;
346   Handle(AIS_Drawer) aDrawer;
347
348   if (!anAIS.IsNull()) {
349     ais = Handle(AIS_LengthDimension)::DownCast(anAIS);
350   }
351
352   if (ais.IsNull())  {
353     if (is2vertices)  {                                        //addition 2
354       gp_Pnt P1 = BRep_Tool::Pnt( TopoDS::Vertex(shape1) );
355       gp_Pnt P2 = BRep_Tool::Pnt( TopoDS::Vertex(shape2) );
356       gp_Pnt P3(P1.Y()-1., P2.X()+1., 0.); 
357       GC_MakePlane mkPlane(P1, P2, P3); 
358       ais = new AIS_LengthDimension (shape1, shape2, mkPlane.Value(), val1,txt);
359     }
360     else if (isface)  {
361       ais = new AIS_LengthDimension (GetFace(shape1),GetFace(shape2),val1,txt);
362     }
363     else if (isedgeface) {
364       ais = new AIS_LengthDimension (GetFace(shape1),GetEdge(shape2),val1,txt);
365     }
366     else  {
367       ais = new AIS_LengthDimension (shape1,shape2,aplane,val1,txt);
368     }
369     if( SaveDrw ) ais->SetAttributes(aDrawer);   
370   }
371   else {
372     if (isface)  {
373       ais->SetFirstShape  (GetFace(shape1));
374       ais->SetSecondShape (GetFace(shape2));
375     }
376     else  {
377       ais->SetFirstShape  (shape1);
378       ais->SetSecondShape (shape2);
379     }
380     if (is2vertices)  {                     //addition 3
381       gp_Pnt P1 = BRep_Tool::Pnt( TopoDS::Vertex(shape1) );
382       gp_Pnt P2 = BRep_Tool::Pnt( TopoDS::Vertex(shape2) );
383       gp_Pnt P3(P1.Y()-1., P2.X()+1., 0.); 
384       GC_MakePlane mkPlane(P1, P2, P3); 
385       ais->SetPlane( mkPlane.Value() );
386     }
387
388     ais->SetValue       (val1);
389     ais->SetText        (txt);
390   }
391   
392   if (is_planar) {
393     Standard_Integer extShape (0);
394 #ifndef BUC60846
395     FindExternalShape (aConst,extShape);
396 #endif
397     ais->SetPlane      (aplane);
398     ais->SetTypeOfDist (typedist);
399     ais->SetExtShape   (extShape);
400   }
401   anAIS = ais;
402 }
403
404 //=======================================================================
405 //function : ComputePerpendicular
406 //purpose  : 
407 //=======================================================================
408 void TPrsStd_ConstraintTools::ComputePerpendicular(const Handle(TDataXtd_Constraint)& aConst,
409                                                   Handle(AIS_InteractiveObject)& anAIS) 
410 {
411   Standard_Integer nbgeom = aConst->NbGeometries();
412   if (nbgeom < 2) {
413 #ifdef DEB
414     cout << "TPrsStd_ConstraintTools::ComputePerpendicular: at leat two constraintes are needed" << endl;
415 #endif
416     NullifyAIS(anAIS);
417     return;
418   }
419   
420   TopoDS_Shape shape1,shape2 ;
421   Handle(Geom_Geometry) ageom3;
422   Standard_Boolean is_planar(aConst->IsPlanar());
423   
424   if (is_planar) GetShapesAndGeom(aConst,shape1,shape2,ageom3);
425   else GetTwoShapes(aConst,shape1,shape2); 
426   if (shape1.IsNull() || shape2.IsNull()) {
427 #ifdef DEB
428     cout << "TPrsStd_ConstraintTools::ComputePerpendicular : null shape" << endl;
429 #endif
430     NullifyAIS(anAIS);
431     return;
432   }
433   GetGoodShape(shape1);
434   GetGoodShape(shape2);
435   //  Update de l'AIS
436   Handle(AIS_PerpendicularRelation) ais;
437   if (anAIS.IsNull()) ais = new AIS_PerpendicularRelation(shape1,shape2);
438   else {
439     ais = Handle(AIS_PerpendicularRelation)::DownCast(anAIS);
440     if (ais.IsNull()) {
441       ais = new AIS_PerpendicularRelation(shape1,shape2);
442     }
443     else {
444       ais->SetFirstShape(shape1);
445       ais->SetSecondShape(shape2);
446     }
447   }
448   
449   if (is_planar) {
450     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
451     if (aplane.IsNull()) {
452 #ifdef DEB
453       cout << "TPrsStd_ConstraintTools::ComputePerpendicular: nul plane" << endl;
454 #endif
455       NullifyAIS(anAIS);
456       return;
457     }
458     ais->SetPlane(aplane);
459   }
460   anAIS = ais;
461 }
462
463 //=======================================================================
464 //function : ComputeParallel
465 //purpose  : 
466 //=======================================================================
467 void TPrsStd_ConstraintTools::ComputeParallel(const Handle(TDataXtd_Constraint)& aConst, 
468                                              Handle(AIS_InteractiveObject)& anAIS) 
469 {
470   Standard_Integer nbgeom = aConst->NbGeometries();
471   if (nbgeom < 2) {
472 #ifdef DEB
473     cout << "TPrsStd_ConstraintTools::ComputeParallel: at least 2 constraintes are needed" << endl;
474 #endif
475     NullifyAIS(anAIS);
476     return;
477   }
478   
479   if (!aConst->IsPlanar()) {
480 #ifdef DEB
481     cout << "TPrsStd_ConstraintTools::ComputeParallel: must be a planar constraint" << endl;
482 #endif
483     NullifyAIS(anAIS);
484     return;
485   }
486
487   TopoDS_Shape shape1,shape2 ;
488   Handle(Geom_Geometry) ageom3;
489   
490   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
491   if (shape1.IsNull() || shape2.IsNull()) {
492 #ifdef DEB
493     cout << "TPrsStd_ConstraintTools::ComputeParallel : null shape" << endl;
494 #endif
495     NullifyAIS(anAIS);
496     return;
497   }
498   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
499   if (aplane.IsNull()) {
500 #ifdef DEB
501     cout << "TPrsStd_ConstraintTools::ComputeParallel: nul plane" << endl;
502 #endif
503     NullifyAIS(anAIS);
504     return;
505   }
506   //  Update de l'AIS
507   GetGoodShape(shape1);
508   GetGoodShape(shape2);
509   Handle(AIS_ParallelRelation) ais;
510   if (anAIS.IsNull()) ais = new AIS_ParallelRelation(shape1,shape2,aplane);
511   else { 
512     ais = Handle(AIS_ParallelRelation)::DownCast(anAIS);
513     if (ais.IsNull()) {
514       ais = new AIS_ParallelRelation(shape1,shape2,aplane);
515     }
516     else {
517       ais->SetFirstShape(shape1);
518       ais->SetSecondShape(shape2);
519       ais->SetPlane(aplane);
520     }
521   }
522   anAIS = ais;
523 }
524 //=======================================================================
525 //function : ComputeSymmetry
526 //purpose  : 
527 //=======================================================================
528 void TPrsStd_ConstraintTools::ComputeSymmetry(const Handle(TDataXtd_Constraint)& aConst,
529                                              Handle(AIS_InteractiveObject)& anAIS) 
530 {
531   Standard_Integer nbgeom = aConst->NbGeometries();
532   if (nbgeom < 3) {
533 #ifdef DEB
534     cout << "TPrsStd_ConstraintTools::ComputeSymmetry: at least 3 constraintes are needed" << endl;
535 #endif
536     NullifyAIS(anAIS);
537     return;
538   }
539
540   Standard_Boolean is_planar(aConst->IsPlanar());
541   if (!is_planar) {
542 #ifdef DEB
543     cout << "TPrsStd_ConstraintTools::ComputeSymmetry: must be a planar constraint" << endl;
544 #endif
545     NullifyAIS(anAIS);
546     return;
547   }
548
549   TopoDS_Shape shape1,shape2,shape3 ;
550   Handle(Geom_Geometry) ageom3;
551   GetShapesAndGeom(aConst,shape1,shape2,shape3,ageom3);
552
553   if (shape1.IsNull() || shape2.IsNull() || shape3.IsNull()) {
554 #ifdef DEB
555     cout << "TPrsStd_ConstraintTools::ComputeSymmetry : null shape" << endl;
556 #endif
557     NullifyAIS(anAIS);
558     return;
559   }
560   GetGoodShape(shape1);
561   GetGoodShape(shape2);
562   GetGoodShape(shape3);
563   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
564   if (aplane.IsNull()) {
565 #ifdef DEB
566     cout << "TPrsStd_ConstraintTools::ComputeSymmetry: null plane" << endl;
567 #endif
568     NullifyAIS(anAIS);
569     return;
570   }
571   //  Update de l'AIS
572   Handle(AIS_SymmetricRelation) ais;
573   if (anAIS.IsNull()) ais = new AIS_SymmetricRelation(shape3,shape1,shape2,aplane);
574   else {
575     ais = Handle(AIS_SymmetricRelation)::DownCast(anAIS);
576     if (ais.IsNull()) {
577       ais = new AIS_SymmetricRelation(shape3,shape1,shape2,aplane);
578     }
579     else {
580       ais->SetFirstShape(shape1);
581       ais->SetSecondShape(shape2);
582       ais->SetPlane(aplane);
583       ais->SetTool(shape3);
584     }
585   }
586   anAIS = ais;
587 }
588
589 //=======================================================================
590 //function : ComputeMidPoint
591 //purpose  : 
592 //=======================================================================
593 void TPrsStd_ConstraintTools::ComputeMidPoint(const Handle(TDataXtd_Constraint)& aConst,
594                                               Handle(AIS_InteractiveObject)& anAIS) 
595 {
596   Standard_Integer nbgeom = aConst->NbGeometries();
597   if (nbgeom < 3)
598     {
599 #ifdef DEB
600       cout << "TPrsStd_ConstraintTools::ComputeSymmetry: at least 3 constraints are needed" << endl;
601 #endif
602       NullifyAIS(anAIS);
603       return;
604     }
605
606   Standard_Boolean is_planar(aConst->IsPlanar());
607   if ( !is_planar )
608     {
609 #ifdef DEB
610       cout << "TPrsStd_ConstraintTools::ComputeSymmetry: must be a planar constraint" << endl;
611 #endif
612       NullifyAIS(anAIS);
613       return;
614     }
615
616   TopoDS_Shape shape1,shape2,shape3;
617   Handle(Geom_Geometry) ageom3;
618   GetShapesAndGeom(aConst,shape1,shape2,shape3,ageom3);
619
620   if (shape1.IsNull() || shape2.IsNull() || shape3.IsNull())
621     {
622 #ifdef DEB
623       cout << "TPrsStd_ConstraintTools::ComputeSymmetry : null shape" << endl;
624 #endif
625       NullifyAIS(anAIS);
626       return;
627     }
628   GetGoodShape(shape1);
629   GetGoodShape(shape2);
630   GetGoodShape(shape3);
631
632   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
633   if (aplane.IsNull())
634     {
635 #ifdef DEB
636       cout << "TPrsStd_ConstraintTools::ComputeSymmetry: null plane" << endl;
637 #endif
638       NullifyAIS(anAIS);
639       return;
640     }
641
642   //  Update de l'AIS
643   Handle(AIS_MidPointRelation) ais;
644   if ( anAIS.IsNull() ) ais = new AIS_MidPointRelation(shape3,shape1,shape2,aplane);
645   else
646     {
647       ais = Handle(AIS_MidPointRelation)::DownCast(anAIS);
648       if (ais.IsNull())
649         {
650           ais = new AIS_MidPointRelation(shape3,shape1,shape2,aplane);
651         }
652       else
653         {
654           ais->SetFirstShape(shape1);
655           ais->SetSecondShape(shape2);
656           ais->SetPlane(aplane);
657           ais->SetTool(shape3);
658         }
659     }
660   anAIS = ais;
661 }
662
663 //=======================================================================
664 //function : ComputeTangent
665 //purpose  : 
666 //=======================================================================
667 void TPrsStd_ConstraintTools::ComputeTangent (const Handle(TDataXtd_Constraint)& aConst, 
668                                              Handle(AIS_InteractiveObject)& anAIS) 
669 {
670   Standard_Integer nbgeom = aConst->NbGeometries();
671   if (nbgeom < 2) {
672 #ifdef DEB
673     cout << "TPrsStd_ConstraintTools::ComputeTangent: at leat two constraintes are needed" << endl;
674 #endif
675     NullifyAIS(anAIS);
676     return;
677   }
678   if (!aConst->IsPlanar()) {
679 #ifdef DEB
680     cout << "TPrsStd_ConstraintTools::ComputeTangent: must be a planar constraint" << endl;
681 #endif
682     NullifyAIS(anAIS);
683     return;
684   }
685   TopoDS_Shape shape1,shape2 ;
686   Handle(Geom_Geometry) ageom3;
687   
688   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
689   if (shape1.IsNull() || shape2.IsNull()) {
690 #ifdef DEB
691     cout << "TPrsStd_ConstraintTools::ComputeTangent : null shape" << endl;
692 #endif
693     NullifyAIS(anAIS);
694     return;
695   }
696   GetGoodShape(shape1);
697   GetGoodShape(shape2);
698   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
699   if (aplane.IsNull()) {
700 #ifdef DEB
701     cout << "TPrsStd_ConstraintTools::ComputeTangent: nul plane" << endl;
702 #endif
703     NullifyAIS(anAIS);
704     return;    
705   }
706   //  Update de l'AIS
707   Handle(AIS_TangentRelation) ais;
708   if (anAIS.IsNull())
709     {
710       ais = new AIS_TangentRelation(shape1,shape2,aplane);
711       ais->SetArrowSize(10000000); // jfa 9/10/2000
712     }
713   else
714     {
715       ais = Handle(AIS_TangentRelation)::DownCast(anAIS);
716       if (ais.IsNull())
717         {
718           ais = new AIS_TangentRelation(shape1,shape2,aplane);
719           ais->SetArrowSize(10000000); // jfa 9/10/2000
720         }
721       else
722         {
723           ais->SetFirstShape(shape1);
724           ais->SetSecondShape(shape2);
725           ais->SetPlane(aplane);
726           ais->SetArrowSize(10000000); // jfa 9/10/2000
727         }
728     }
729   anAIS = ais;
730 }
731
732 //=======================================================================
733 //function : ComputeAngleForOneFace
734 //purpose  : computes AngleDimension for one-conical-face case
735 //=======================================================================
736 void TPrsStd_ConstraintTools::ComputeAngleForOneFace (const Handle(TDataXtd_Constraint)& aConst,
737                                            Handle(AIS_InteractiveObject)& anAIS) 
738 {
739  
740   TopoDS_Shape shape;
741   Handle(Geom_Geometry) ageom3;
742   
743   GetOneShape( aConst, shape ); 
744   if (shape.IsNull() ) {
745 #ifdef DEB
746     cout << "TPrsStd_ConstraintTools::ComputeAngleForOneFace : null shape" << endl;
747 #endif
748     NullifyAIS(anAIS);
749     return;
750   }
751
752   Standard_Real val1;
753   TCollection_ExtendedString txt;
754   TPrsStd_ConstraintTools::ComputeTextAndValue (aConst,val1,txt,Standard_True);  
755   
756   Handle(AIS_AngleDimension) ais;
757   TopoDS_Face face;
758   if (!anAIS.IsNull()) {
759     ais = Handle(AIS_AngleDimension)::DownCast(anAIS);
760     if(ais.IsNull()) {
761       face = TopoDS::Face( shape );
762       ais =  new AIS_AngleDimension ( face, val1, txt);
763     }
764     else {
765       ais->SetConeFace(TopoDS::Face( shape ));
766       ais->SetValue(val1);
767       ais->SetText(txt);
768     }
769   }
770   else {
771     face = TopoDS::Face( shape );
772     ais =  new AIS_AngleDimension ( face, val1, txt);
773   } 
774
775   anAIS = ais;
776 }
777
778 //====================================================================
779 static Standard_Boolean CheckIsShapeCompound(TopoDS_Shape& shape, TopoDS_Face& aFace)
780 {
781   if (shape.ShapeType() == TopAbs_COMPOUND) {
782     TopTools_IndexedMapOfShape aFaceMap;
783     TopExp::MapShapes(shape, TopAbs_FACE, aFaceMap);
784     for(Standard_Integer i = 1;i <= aFaceMap.Extent();i++) 
785       {
786         aFace = TopoDS::Face(aFaceMap.FindKey(i));
787         if(!aFace.IsNull()) {
788           shape = aFace;
789           return (Standard_True);
790         }
791       }
792   }
793 #ifdef DEB
794   cout << "TPrsStd::Compute angle : Shape is not Compound or is Null" <<endl;
795 #endif
796   return (Standard_False);
797 }
798 //=======================================================================
799 //function : ComputeAngle
800 //purpose  : 
801 //=======================================================================
802 void TPrsStd_ConstraintTools::ComputeAngle (const Handle(TDataXtd_Constraint)& aConst,
803                                            Handle(AIS_InteractiveObject)& anAIS) 
804 {
805   Standard_Integer nbgeom = aConst->NbGeometries();
806   if (nbgeom < 2) {
807     if( nbgeom == 1 ) { ComputeAngleForOneFace( aConst, anAIS ); return; }
808 #ifdef DEB
809     cout << "TPrsStd_ConstraintTools::ComputeAngle: at least 2 constraints are needed" << endl;
810 #endif
811     NullifyAIS(anAIS);
812     return;
813   }
814   
815   TopoDS_Shape shape1,shape2 ;
816   Handle(Geom_Geometry) ageom3;
817   
818   GetShapesAndGeom (aConst,shape1,shape2,ageom3);
819   if (shape1.IsNull() || shape2.IsNull()) {
820 #ifdef DEB
821     cout << "TPrsStd_ConstraintTools::ComputeAngle : null shape" << endl;
822 #endif
823     NullifyAIS(anAIS);
824     return;
825   }
826   
827   Standard_Boolean isCurvilinear = Standard_False;
828   if (ageom3.IsNull()) {
829     // on essaie de le calculer
830     
831     TopoDS_Face  aFace;
832     if (shape1.ShapeType() == TopAbs_WIRE)  {
833       BRepBuilderAPI_MakeFace MkF (TopoDS::Wire(shape1),Standard_True);
834       if (MkF.IsDone())  {
835         aFace = MkF.Face();
836         shape1 = aFace;
837       }
838     }
839     else
840       if (shape1.ShapeType() == TopAbs_FACE)
841         aFace    = TopoDS::Face(shape1);
842       else
843         if(!CheckIsShapeCompound(shape1, aFace)) {
844 #ifdef DEB
845         cout << "Compute angle : Geom type = " << shape1.ShapeType()
846           << " non traite"<<endl;
847 #endif
848         NullifyAIS(anAIS);
849         return;      
850       }
851
852     gp_Ax1 anax1aFace1;
853     gp_Pln aPlnaFace1;
854
855     BRepAdaptor_Surface   aSurfaFace (aFace);
856     GeomAbs_SurfaceType aTypeaFace = aSurfaFace.GetType();
857     if (aTypeaFace  == GeomAbs_Plane) {
858       aPlnaFace1 = aSurfaFace.Plane();
859       anax1aFace1 = aPlnaFace1.Axis(); // Normale au plan
860     } else if (aTypeaFace  == GeomAbs_Cylinder) {
861       gp_Cylinder aCylaFace = aSurfaFace.Cylinder();
862       anax1aFace1 = aCylaFace.Axis();
863     } else if (aTypeaFace  == GeomAbs_Cone) {
864       gp_Cone aCone = aSurfaFace.Cone();
865       anax1aFace1 = aCone.Axis();  
866     } else if (aTypeaFace  == GeomAbs_Torus) {
867       gp_Torus aTore = aSurfaFace.Torus();
868       anax1aFace1 = aTore.Axis();  
869     } else {
870 #ifdef DEB
871       cout<<"Compute angle"<<aTypeaFace<<" non traite"<<endl;
872 #endif
873       NullifyAIS(anAIS);
874       return;      
875     }
876
877     gp_Ax1 anax1aFace2;
878     gp_Pln aPlnaFace2;
879     if (shape2.ShapeType() == TopAbs_WIRE)  {
880       BRepBuilderAPI_MakeFace MkF (TopoDS::Wire(shape2),Standard_True);
881       if (MkF.IsDone())  {
882         aFace = MkF.Face();
883         shape2 = aFace;
884       }
885     }
886     else
887       if (shape2.ShapeType() == TopAbs_FACE)
888         aFace    = TopoDS::Face(shape2); 
889     else  
890       if(!CheckIsShapeCompound(shape2, aFace)) {
891 #ifdef DEB
892         cout << "Compute angle : Geom type = " << shape2.ShapeType()
893           << " non traite"<<endl;
894 #endif
895         NullifyAIS(anAIS);
896         return;      
897       }
898     
899     aSurfaFace.Initialize(aFace);
900     aTypeaFace = aSurfaFace.GetType();
901     if (aTypeaFace  == GeomAbs_Plane) {
902       aPlnaFace2 = aSurfaFace.Plane();
903       anax1aFace2 = aPlnaFace2.Axis(); // Normale au plan
904     } else if (aTypeaFace  == GeomAbs_Cylinder) {
905       gp_Cylinder aCylaFace = aSurfaFace.Cylinder();
906       anax1aFace2 = aCylaFace.Axis();
907     } else if (aTypeaFace  == GeomAbs_Cone) {
908       gp_Cone aCone = aSurfaFace.Cone();
909       anax1aFace2 = aCone.Axis();  
910     } else if (aTypeaFace  == GeomAbs_Torus) {
911       gp_Torus aTore = aSurfaFace.Torus();
912       anax1aFace2 = aTore.Axis();  
913     } else {
914 #ifdef DEB
915       cout << "Compute angle " << aTypeaFace << " non traite"<<endl;
916 #endif
917       NullifyAIS(anAIS);
918       return;      
919     }
920
921     if (aTypeaFace==GeomAbs_Plane) {
922       if (!anax1aFace1.IsParallel(anax1aFace2, Precision::Angular())) {
923         
924         IntAna_QuadQuadGeo IntersectPlane (aPlnaFace1, aPlnaFace2, Precision::Angular(), Precision::Angular());
925         if (IntersectPlane.IsDone() &&
926             (IntersectPlane.TypeInter() != IntAna_Empty))  {
927           gp_Lin aLine = IntersectPlane.Line(1);
928           Handle(Geom_Line) computedgeom3 = new Geom_Line (aLine);
929           ageom3 = computedgeom3;
930         } else {
931 #ifdef DEB
932           cout<<"Compute angle insertection of planes failed"<<endl;
933 #endif
934           NullifyAIS(anAIS);
935           return;            
936         }
937       } else {
938         
939 #ifdef DEB
940         cout<<"Compute angle faces are //"<<endl;
941 #endif
942         NullifyAIS(anAIS);
943         return;            
944       }
945     } else {
946       // Curvilinear faces...
947       isCurvilinear = Standard_True;
948     }
949   } // endif (ageom3.IsNull())
950
951
952   Standard_Boolean isplan(Standard_False);
953
954   if (!isCurvilinear) {
955     if (ageom3->IsKind(STANDARD_TYPE(Geom_Plane))) isplan = Standard_True;
956     else if (ageom3->IsKind(STANDARD_TYPE(Geom_Line))) isplan = Standard_False;
957     else {
958 #ifdef DEB
959       cout << "TPrsStd_ConstraintTools::ComputeAngle: unknown 3rd arg " << endl;
960 #endif
961       NullifyAIS(anAIS);
962       return;
963     }
964   }
965   Standard_Real val1;
966   TCollection_ExtendedString txt;
967   ComputeTextAndValue (aConst,val1,txt,Standard_True);  
968   
969   Standard_Boolean toCreate (Standard_True);
970   Standard_Boolean isface(shape1.ShapeType()==TopAbs_FACE);
971   
972   Handle(AIS_AngleDimension) ais;
973   if (!anAIS.IsNull()) {
974     ais = Handle(AIS_AngleDimension)::DownCast(anAIS);
975     if( ais.IsNull() ) {
976       toCreate = Standard_True;
977     }
978     else toCreate = Standard_False;
979   }
980   
981   Standard_Integer ExtShape(0);
982   if (toCreate)  {
983     // Creation de l'AIS
984     if (isplan) {
985       if(!isface) {
986         FindExternalShape(aConst,ExtShape);
987         GetGoodShape(shape1);
988         GetGoodShape(shape2);
989         ais = new AIS_AngleDimension (TopoDS::Edge(shape1),
990                                       TopoDS::Edge(shape2),
991                                       (Handle(Geom_Plane)&) ageom3,val1,txt);
992         ais->SetExtShape(ExtShape);
993       }
994     }
995     else { 
996       if (isCurvilinear) {
997         ais = new AIS_AngleDimension (TopoDS::Face(shape1),
998                                       TopoDS::Face(shape2),val1,txt);
999       }
1000       else if (isface) {
1001         ais =  new AIS_AngleDimension (TopoDS::Face(shape1),
1002                                        TopoDS::Face(shape2),
1003                                        ((Handle(Geom_Line)&) ageom3)->Position(),val1,txt);
1004       }
1005     }
1006   }
1007   else {
1008     // Update de l'AIS
1009     if (isplan) {
1010       GetGoodShape(shape1);
1011       GetGoodShape(shape2);
1012     }
1013     ais->SetFirstShape(shape1);
1014     ais->SetSecondShape(shape2);
1015     ais->SetValue(val1);
1016     ais->SetText(txt);
1017     if (isplan)
1018       ais->SetPlane ((Handle(Geom_Plane)&) ageom3);
1019     else if (!isCurvilinear)
1020       ais->SetAxis (((Handle(Geom_Line)&) ageom3)->Position());
1021   }
1022   anAIS = ais;
1023 }
1024
1025
1026 //=======================================================================
1027 //function : ComputeConcentric
1028 //purpose  : 
1029 //=======================================================================
1030 void TPrsStd_ConstraintTools::ComputeConcentric(const Handle(TDataXtd_Constraint)& aConst,
1031                                                Handle(AIS_InteractiveObject)& anAIS) 
1032 {
1033   Standard_Integer nbgeom = aConst->NbGeometries();
1034   if (nbgeom < 2) {
1035     Standard_ProgramError::Raise ("TPrsStd_ConstraintTools::ComputeConcentric: at least 2 constraintes are needed");
1036   }
1037   if (!aConst->IsPlanar()) {
1038 #ifdef DEB
1039     cout << "TPrsStd_ConstraintTools::ComputeConcentric: must be a planar constraint" << endl;
1040 #endif
1041     NullifyAIS(anAIS);
1042     return;
1043   }
1044   TopoDS_Shape shape1,shape2 ;
1045   Handle(Geom_Geometry) ageom3;
1046   
1047   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
1048   if (shape1.IsNull() || shape2.IsNull()) {
1049 #ifdef DEB
1050     cout << "TPrsStd_ConstraintTools::ComputeConcentric : null shape" << endl;
1051 #endif
1052     NullifyAIS(anAIS);
1053     return;
1054   }
1055
1056   GetGoodShape(shape1);
1057   GetGoodShape(shape2);
1058
1059 //ota : to allow concentric constraint display between vertex and edge
1060   if (shape1.ShapeType() != TopAbs_EDGE && shape2.ShapeType() != TopAbs_EDGE) {
1061 #ifdef DEB
1062     cout << "TPrsStd_ConstraintTools::ComputeConcentric: concentric between two vertexes : NOT DISPLAYED" << endl;;
1063 #endif
1064     NullifyAIS(anAIS);
1065     return;
1066   }
1067
1068   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
1069   if (aplane.IsNull()) {
1070 #ifdef DEB
1071     cout << "TPrsStd_ConstraintTools::ComputeConcentric: nul plane" << endl;;
1072 #endif
1073     NullifyAIS(anAIS);
1074     return;
1075   }
1076   //  Update de l'AIS
1077   Handle(AIS_ConcentricRelation) ais;
1078   if (!anAIS.IsNull()) {
1079     ais = Handle(AIS_ConcentricRelation)::DownCast(anAIS);
1080     if (ais.IsNull()) {
1081       ais = new AIS_ConcentricRelation (shape1,shape2,aplane);
1082     } 
1083     else {
1084       ais->SetFirstShape(shape1);
1085       ais->SetSecondShape(shape2);
1086       ais->SetPlane(aplane);
1087     }
1088   }
1089   else {
1090     ais = new AIS_ConcentricRelation (shape1,shape2,aplane);
1091   }
1092
1093   anAIS = ais;
1094 }
1095
1096 //=======================================================================
1097 //function : ComputeRadius
1098 //purpose  : 
1099 //=======================================================================
1100 void TPrsStd_ConstraintTools::ComputeRadius (const Handle(TDataXtd_Constraint)& aConst,
1101                                             Handle(AIS_InteractiveObject)& anAIS) 
1102 {
1103   Standard_Integer nbgeom = aConst->NbGeometries();
1104   if (nbgeom < 1) {
1105 #ifdef DEB
1106     cout << "TPrsStd_ConstraintTools::ComputeRadius: at least one constrainte is needed" << endl;    
1107 #endif
1108     NullifyAIS(anAIS);
1109     return;
1110   }
1111
1112   TopoDS_Shape shape1 ;
1113   GetOneShape (aConst,shape1);
1114   if (shape1.IsNull()) {
1115 #ifdef DEB
1116     cout << "TPrsStd_ConstraintTools::ComputeRadius: null shape" << endl;
1117 #endif
1118     NullifyAIS(anAIS);
1119     return;
1120   }
1121
1122   // POP on teste si ce n'est pas un compound
1123   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1124       shape1.ShapeType()==TopAbs_COMPSOLID ||
1125       shape1.ShapeType()==TopAbs_SOLID ||
1126       shape1.ShapeType()==TopAbs_SHELL ) {
1127 #ifdef DEB
1128     cout << "TPrsStd_ConstraintTools::ComputeRadius: not good shape" << endl;
1129 #endif
1130     NullifyAIS(anAIS);
1131     return;
1132   }
1133       
1134   if (IsFace(shape1))
1135     shape1 = GetFace(shape1);
1136
1137   Standard_Real val1;
1138   TCollection_ExtendedString txt;
1139   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1140
1141   //  Update de l'AIS
1142   Standard_Boolean isplanar(aConst->IsPlanar());
1143   if (isplanar) GetGoodShape(shape1);
1144
1145   Handle(AIS_RadiusDimension) ais;
1146   if (!anAIS.IsNull()) {
1147     ais = Handle(AIS_RadiusDimension)::DownCast(anAIS);
1148     if (ais.IsNull()) {
1149       ais = new AIS_RadiusDimension (shape1,val1,txt);
1150     }
1151     else {
1152       ais->SetValue(val1);
1153       ais->SetFirstShape(shape1);
1154       ais->SetText(txt);    
1155     }
1156   }
1157   else ais = new AIS_RadiusDimension (shape1,val1,txt);
1158
1159   if (isplanar) {
1160     Handle(Geom_Geometry) ageom2;
1161     GetGeom(aConst,ageom2);
1162     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1163     if (aplane.IsNull()) {
1164 #ifdef DEB
1165       cout << "TPrsStd_ConstraintTools::ComputeRadius: nul plane" << endl;
1166 #endif
1167       NullifyAIS(anAIS);
1168       return;
1169     }
1170     ais->SetPlane(aplane);
1171     ais->SetDrawFromCenter(Standard_False);
1172   }
1173   anAIS = ais;
1174 }
1175 // ota -- begin --
1176 //=======================================================================
1177 //function : ComputeMinRadius
1178 //purpose  : 
1179 //=======================================================================
1180 void TPrsStd_ConstraintTools::ComputeMinRadius (const Handle(TDataXtd_Constraint)& aConst,
1181                                                 Handle(AIS_InteractiveObject)& anAIS) 
1182 {
1183   Standard_Integer nbgeom = aConst->NbGeometries();
1184   if (nbgeom < 1) {
1185 #ifdef DEB
1186     cout << "TPrsStd_ConstraintTools::ComputeMinRadius: at least one constrainte is needed" << endl;    
1187 #endif
1188     NullifyAIS(anAIS);
1189     return;
1190   }
1191
1192   TopoDS_Shape shape1 ;
1193   GetOneShape (aConst,shape1);
1194   if (shape1.IsNull()) {
1195 #ifdef DEB
1196     cout << "TPrsStd_ConstraintTools::ComputeMinradius: null shape" << endl;
1197 #endif
1198     NullifyAIS(anAIS);
1199     return;
1200   }
1201
1202   // POP on teste si ce n'est pas un compound
1203   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1204       shape1.ShapeType()==TopAbs_COMPSOLID ||
1205       shape1.ShapeType()==TopAbs_SOLID ||
1206       shape1.ShapeType()==TopAbs_SHELL ) {
1207 #ifdef DEB
1208     cout << "TPrsStd_ConstraintTools::ComputeMinRadius: not good shape" << endl;
1209 #endif
1210     NullifyAIS(anAIS);
1211     return;
1212   }
1213       
1214   if (IsFace(shape1))
1215     shape1 = GetFace(shape1);
1216
1217   Standard_Real val1;
1218   TCollection_ExtendedString txt;
1219   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1220
1221   //  Update de l'AIS
1222   Standard_Boolean isplanar(aConst->IsPlanar());
1223   if (isplanar) GetGoodShape(shape1);
1224
1225   Handle(AIS_MinRadiusDimension) ais;
1226   if (!anAIS.IsNull()) {
1227     ais = Handle(AIS_MinRadiusDimension)::DownCast(anAIS);
1228     if (ais.IsNull()) {
1229       ais = new AIS_MinRadiusDimension (shape1,val1,txt);
1230     }
1231     else {
1232       ais->SetValue(val1);
1233       ais->SetFirstShape(shape1);
1234       ais->SetText(txt);    
1235     }
1236   }
1237   else ais = new AIS_MinRadiusDimension (shape1,val1,txt);
1238
1239   if (isplanar) {
1240     Handle(Geom_Geometry) ageom2;
1241     GetGeom(aConst,ageom2);
1242     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1243     if (aplane.IsNull()) {
1244 #ifdef DEB
1245       cout << "TPrsStd_ConstraintTools::ComputeMinRadius: nul plane" << endl;
1246 #endif
1247       NullifyAIS(anAIS);
1248       return;
1249     }
1250     ais->SetPlane(aplane);
1251   }
1252   anAIS = ais;
1253 }
1254
1255 //=======================================================================
1256 //function : ComputeMaxRadius
1257 //purpose  : 
1258 //=======================================================================
1259 void TPrsStd_ConstraintTools::ComputeMaxRadius (const Handle(TDataXtd_Constraint)& aConst,
1260                                                 Handle(AIS_InteractiveObject)& anAIS) 
1261 {
1262   Standard_Integer nbgeom = aConst->NbGeometries();
1263   if (nbgeom < 1) {
1264 #ifdef DEB
1265     cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: at least one constrainte is needed" << endl;    
1266 #endif
1267     NullifyAIS(anAIS);
1268     return;
1269   }
1270
1271   TopoDS_Shape shape1 ;
1272   GetOneShape (aConst,shape1);
1273   if (shape1.IsNull()) {
1274 #ifdef DEB
1275     cout << "TPrsStd_ConstraintTools::ComputeMaxradius: null shape" << endl;
1276 #endif
1277     NullifyAIS(anAIS);
1278     return;
1279   }
1280
1281   // POP on teste si ce n'est pas un compound
1282   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1283       shape1.ShapeType()==TopAbs_COMPSOLID ||
1284       shape1.ShapeType()==TopAbs_SOLID ||
1285       shape1.ShapeType()==TopAbs_SHELL ) {
1286 #ifdef DEB
1287     cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: not good shape" << endl;
1288 #endif
1289     NullifyAIS(anAIS);
1290     return;
1291   }
1292
1293   if (IsFace(shape1))
1294     shape1 = GetFace(shape1);
1295
1296   Standard_Real val1;
1297   TCollection_ExtendedString txt;
1298   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1299
1300   //  Update de l'AIS
1301   Standard_Boolean isplanar(aConst->IsPlanar());
1302   if (isplanar) GetGoodShape(shape1);
1303
1304   Handle(AIS_MaxRadiusDimension) ais;
1305   if (!anAIS.IsNull()) {
1306     ais = Handle(AIS_MaxRadiusDimension)::DownCast(anAIS);
1307     if (ais.IsNull()) {
1308       ais = new AIS_MaxRadiusDimension (shape1,val1,txt);
1309     }
1310     else {
1311       ais->SetValue(val1);
1312       ais->SetFirstShape(shape1);
1313       ais->SetText(txt);    
1314     }
1315   }
1316   else ais = new AIS_MaxRadiusDimension (shape1,val1,txt);
1317
1318   if (isplanar) {
1319     Handle(Geom_Geometry) ageom2;
1320     GetGeom(aConst,ageom2);
1321     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1322     if (aplane.IsNull()) {
1323 #ifdef DEB
1324       cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: nul plane" << endl;
1325 #endif
1326       NullifyAIS(anAIS);
1327       return;
1328     }
1329     ais->SetPlane(aplane);
1330   }
1331   anAIS = ais;
1332 }
1333
1334 //=======================================================================
1335 //function : ComputeEqualDistance
1336 //purpose  : 
1337 //=======================================================================
1338 void TPrsStd_ConstraintTools::ComputeEqualDistance(const Handle(TDataXtd_Constraint)& aConst,
1339                                                    Handle(AIS_InteractiveObject)& anAIS) 
1340 {
1341   Standard_Integer nbgeom = aConst->NbGeometries();
1342   if (nbgeom < 4) {
1343       cout << "TPrsStd_ConstraintTools::ComputeEqual: at least four geometries are needed" << endl;;
1344       NullifyAIS(anAIS);
1345       return;
1346     }
1347   TopoDS_Shape aShape1, aShape2, aShape3, aShape4;
1348   Handle(Geom_Geometry) aGeom;
1349   GetShapesAndGeom(aConst, aShape1, aShape2, aShape3, aShape4, aGeom);
1350    if (aShape1.IsNull()||aShape2.IsNull()||
1351        aShape3.IsNull()||aShape4.IsNull()) {
1352 #ifdef DEB
1353     cout << "TPrsStd_ConstraintTools::ComputeEqualDistance : null shape" << endl;
1354 #endif
1355     NullifyAIS(anAIS);
1356     return;
1357   }
1358
1359   GetGoodShape(aShape1);
1360   GetGoodShape(aShape2);
1361   GetGoodShape(aShape3);
1362   GetGoodShape(aShape4);
1363   
1364   if (!CheckShapesPair(aShape1, aShape2) || 
1365       !CheckShapesPair(aShape3, aShape4)){
1366 #ifdef DEB
1367         cout << "TPrsStd_ConstraintTools::ComputeEqualDistance : at least one pair of shapes is incorrect"<<endl;
1368 #endif
1369         NullifyAIS(anAIS);
1370         return;
1371       }
1372
1373   //Get the plane
1374   Standard_Boolean IsPlanar(aConst->IsPlanar());
1375   Handle(Geom_Plane) aPlane ;
1376   if(IsPlanar) aPlane = Handle(Geom_Plane)::DownCast(aGeom) ; 
1377  
1378   if (!IsPlanar || aPlane.IsNull()) {
1379     //create the plane
1380 #ifdef DEB
1381     cout<< "The constraint plane is not assigned "<< endl;
1382 #endif
1383     NullifyAIS(anAIS);
1384     return;
1385   }
1386   
1387   //Update AIS
1388   Handle(AIS_EqualDistanceRelation) ais; 
1389   if (!anAIS.IsNull()) {
1390     {
1391       ais = Handle(AIS_EqualDistanceRelation)::DownCast(anAIS);
1392     
1393       if (ais.IsNull()) 
1394         ais = new AIS_EqualDistanceRelation(aShape1, aShape2, aShape3, aShape4, aPlane);
1395       
1396       else {
1397         ais->SetFirstShape(aShape1);
1398         ais->SetSecondShape(aShape2);
1399         ais->SetShape3(aShape3);
1400         ais->SetShape4(aShape4);
1401         ais->SetPlane(aPlane);
1402       }
1403     }
1404   }
1405   else ais = new AIS_EqualDistanceRelation(aShape1, aShape2, aShape3, aShape4, aPlane);
1406   
1407   anAIS = ais;  
1408
1409   return;
1410 }
1411
1412 //======================================================================
1413 // function : CheckShapesPair
1414 // purpose  : checks the types of two shapes. 
1415 //            If the types aShape1 and aShape2 are EDGE - EDGE,
1416 //                                              or EDGE - VERTEX,
1417 //                                              or VERTEX - VERTEX,
1418 //                                              or CIRCLE - CIRCLE,
1419 //                                              or CIRCLE - VERTEX,
1420 //            then function returns TRUE, otherwise FALSE.
1421 //======================================================================
1422 static Standard_Boolean CheckShapesPair(const TopoDS_Shape& aShape1, 
1423                                     const TopoDS_Shape& aShape2)
1424 {
1425   //Check whether the shapes form a correct pair.
1426   if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_EDGE)
1427     {
1428       BRepAdaptor_Curve aCurve1(TopoDS::Edge(aShape1));
1429       BRepAdaptor_Curve aCurve2(TopoDS::Edge(aShape2));
1430       if (aCurve1.GetType() == GeomAbs_Line && aCurve2.GetType() == GeomAbs_Line)
1431         { //Are lines parallel ?
1432           gp_Dir aDir1 = aCurve1.Line().Direction();
1433           gp_Dir aDir2 = aCurve2.Line().Direction();
1434           if (!(aDir1.IsParallel(aDir2, Precision::Confusion()))) {
1435 #ifdef DEB
1436             cout << " Lines are not parallel"<<endl;
1437 #endif
1438             return Standard_False;
1439           }
1440         }
1441       else if (aCurve1.GetType() == GeomAbs_Circle && aCurve2.GetType() == GeomAbs_Circle)
1442         {
1443           gp_Pnt aCntr1 = aCurve1.Circle().Location(); //get the circle center
1444           gp_Pnt aCntr2 = aCurve2.Circle().Location(); //get the circle center
1445           if (!aCntr1.IsEqual(aCntr2,Precision::Confusion())){
1446 #ifdef DEB
1447             cout << " Circles are not concentric"<<endl;
1448 #endif
1449             return Standard_False;
1450           }
1451         }
1452       else {
1453 #ifdef DEB
1454         cout << "Incorrect pair of curves "<<endl;
1455 #endif
1456         return Standard_False;
1457       }
1458     }
1459   else if ( aShape1.ShapeType() != TopAbs_VERTEX || aShape2.ShapeType() != TopAbs_VERTEX)
1460     {
1461       gp_Pnt aPnt;
1462       BRepAdaptor_Curve aCurve;
1463       if ( aShape1.ShapeType() == TopAbs_VERTEX) {
1464         aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
1465         aCurve.Initialize(TopoDS::Edge(aShape2));
1466       }
1467       else {
1468         aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
1469         aCurve.Initialize(TopoDS::Edge(aShape1));
1470       }
1471       if ( aCurve.GetType() == GeomAbs_Circle)
1472         {
1473           gp_Pnt aCntr = aCurve.Circle().Location();
1474           if (!aCntr.IsEqual(aPnt, Precision::Confusion())){
1475 #ifdef DEB
1476             cout << " The point doesn't coincide with the circle center"<<endl;
1477 #endif
1478             return Standard_False;
1479           }
1480         }
1481     }
1482   return Standard_True;
1483 }
1484
1485 //=======================================================================
1486 //function : ComputeEqualRadius
1487 //purpose  : 
1488 //=======================================================================
1489 void TPrsStd_ConstraintTools::ComputeEqualRadius(const Handle(TDataXtd_Constraint)& aConst,
1490                                                  Handle(AIS_InteractiveObject)& anAIS) 
1491 {
1492   Standard_Integer nbgeom = aConst->NbGeometries();
1493   if (nbgeom < 2) {
1494 #ifdef DEB
1495     cout << "TPrsStd_ConstraintTools::ComputeEqualRadius: at least two geometries are needed" << endl;;
1496 #endif
1497     NullifyAIS(anAIS);
1498     return;
1499   }
1500   TopoDS_Shape shape1, shape2;
1501   Handle(Geom_Geometry) ageom3;
1502   
1503   GetShapesAndGeom(aConst, shape1, shape2, ageom3);
1504   if (shape1.IsNull()||shape2.IsNull()) {
1505 #ifdef DEB
1506     cout << "TPrsStd_ConstraintTools::ComputeEqualRadius : null shape" << endl;
1507 #endif
1508     NullifyAIS(anAIS);
1509     return;
1510   }
1511   
1512   //  Update AIS
1513   Standard_Boolean IsPlanar(aConst->IsPlanar());
1514  
1515   GetGoodShape(shape1);
1516   GetGoodShape(shape2);
1517   const TopoDS_Edge edge1 = TopoDS::Edge(shape1);
1518   const TopoDS_Edge edge2 = TopoDS::Edge(shape2);
1519   Handle(Geom_Plane) aplane ;
1520   
1521   if (IsPlanar) aplane = Handle(Geom_Plane)::DownCast(ageom3) ;
1522   
1523   if (!IsPlanar || aplane.IsNull()) {
1524     // check are the planes of edge1 and edge2 coincident
1525     BRepAdaptor_Curve aCurve( edge1 );
1526     Handle( Geom_Curve ) aProjCurve = aCurve.Curve().Curve();
1527     gp_Circ aCircle = (Handle( Geom_Circle )::DownCast( aProjCurve ))->Circ();
1528     gp_Ax3 anAx31(aCircle.Position()); //get the circle axis
1529     // get the circle plane 
1530     Handle(Geom_Plane) aPlane1 = new Geom_Plane (anAx31);
1531
1532     aCurve.Initialize(edge2);
1533     aProjCurve = aCurve.Curve().Curve();
1534     aCircle = (Handle( Geom_Circle )::DownCast( aProjCurve ))->Circ();
1535     gp_Ax3 anAx32(aCircle.Position()); //get the circle axis
1536     // get the circle plane 
1537     Handle(Geom_Plane) aPlane2 = new Geom_Plane (anAx32);
1538
1539     Standard_Real A, B, C ,D1, D2;
1540     aPlane1->Coefficients(A, B, C, D1);//Get normalized coefficients
1541     aPlane2->Coefficients(A, B, C, D2);//Get normalized coefficients
1542     const gp_Dir& aDir1 = anAx31.Direction();
1543     const gp_Dir& aDir2 = anAx32.Direction();
1544     
1545     if(Abs(D1 - D2) < Precision::Confusion() &&
1546        aDir1.IsParallel(aDir2, Precision::Confusion()))
1547       aplane = aPlane2;
1548     else {
1549 #ifdef DEB
1550       cout << "TPrsStd_ConstraintTools::ComputeRadiusRelation: nul plane" << endl;
1551 #endif
1552       NullifyAIS(anAIS);
1553       return;
1554     }
1555   }   
1556   Handle(AIS_EqualRadiusRelation) ais;
1557   if (!anAIS.IsNull()) {
1558     ais = Handle(AIS_EqualRadiusRelation)::DownCast(anAIS);
1559     
1560     if (ais.IsNull()) {
1561       ais = new AIS_EqualRadiusRelation(edge1, edge2, aplane);
1562       }
1563     else {
1564       ais->SetFirstShape(shape1);
1565       ais->SetSecondShape(shape2);
1566       ais->SetPlane(aplane);
1567     }
1568   }
1569   else {
1570     ais = new AIS_EqualRadiusRelation(edge1, edge2, aplane);
1571   }
1572   
1573   anAIS = ais;
1574 }
1575 //ota -- end --
1576
1577 //=======================================================================
1578 //function : ComputeDiameter
1579 //purpose  : 
1580 //=======================================================================
1581 void TPrsStd_ConstraintTools::ComputeDiameter(const Handle(TDataXtd_Constraint)& aConst,
1582                                              Handle(AIS_InteractiveObject)& anAIS) 
1583 {
1584   Standard_Integer nbgeom = aConst->NbGeometries();
1585   if (nbgeom < 1) {
1586 #ifdef DEB
1587     cout << "TPrsStd_ConstraintTools::ComputeDiameter: at least one constrainte is needed" << endl;;
1588 #endif
1589     NullifyAIS(anAIS);
1590     return;
1591   }
1592   TopoDS_Shape shape1 ;
1593   
1594   GetOneShape(aConst,shape1);
1595   if (shape1.IsNull()) {
1596 #ifdef DEB
1597     cout << "TPrsStd_ConstraintTools::ComputeDiameter : null shape" << endl;
1598 #endif
1599     NullifyAIS(anAIS);
1600     return;
1601   }
1602   Standard_Real val1;
1603   TCollection_ExtendedString txt;
1604   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1605
1606   //  Update de l'AIS
1607   Standard_Boolean IsPlanar(aConst->IsPlanar());
1608   if (IsPlanar) GetGoodShape(shape1);
1609   Handle(AIS_DiameterDimension) ais;
1610   if (!anAIS.IsNull()) {
1611     ais = Handle(AIS_DiameterDimension)::DownCast(anAIS);
1612     if (ais.IsNull()) {
1613       ais = new AIS_DiameterDimension (shape1,val1,txt);
1614     }
1615     else {
1616       ais->SetFirstShape(shape1);
1617       ais->SetValue(val1);
1618       ais->SetText(txt);
1619     }
1620   }
1621   else ais = new AIS_DiameterDimension (shape1,val1,txt);
1622
1623   if (IsPlanar) {
1624     Handle(Geom_Geometry) ageom2;
1625     GetGeom(aConst,ageom2);
1626     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1627     if (aplane.IsNull()) {
1628 #ifdef DEB
1629       cout << "TPrsStd_ConstraintTools::ComputeDiameter: nul plane" << endl;
1630 #endif
1631       NullifyAIS(anAIS);
1632       return;
1633     }
1634     ais->SetPlane(aplane);
1635   }
1636   anAIS = ais;
1637 }
1638
1639
1640 //=======================================================================
1641 //function : ComputeFix
1642 //purpose  : 
1643 //=======================================================================
1644 void TPrsStd_ConstraintTools::ComputeFix(const Handle(TDataXtd_Constraint)& aConst,
1645                                         Handle(AIS_InteractiveObject)& anAIS) 
1646 {
1647   Standard_Integer nbgeom = aConst->NbGeometries();
1648   if (nbgeom < 1) {
1649 #ifdef DEB
1650     cout << "TPrsStd_ConstraintTools::ComputeFix: at least one constrainte is needed" << endl;;
1651 #endif
1652     NullifyAIS(anAIS);
1653     return;
1654   }
1655   if (!aConst->IsPlanar()) {
1656 #ifdef DEB
1657     cout << "TPrsStd_ConstraintTools::ComputeFix: must be a planar constraint" << endl;;
1658 #endif
1659     NullifyAIS(anAIS);
1660     return;
1661   }
1662
1663   TopoDS_Shape shape1 ;
1664   Handle(Geom_Geometry) ageom2;
1665   
1666   GetOneShape(aConst,shape1);
1667   if (shape1.IsNull()) {
1668 #ifdef DEB
1669     cout << "TPrsStd_ConstraintTools::ComputeFix : null shape" << endl;
1670 #endif
1671     NullifyAIS(anAIS);
1672     return;
1673   }  
1674   GetGoodShape(shape1);
1675   GetGeom(aConst,ageom2);
1676   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1677   if (aplane.IsNull()) {
1678 #ifdef DEB
1679     cout << "TPrsStd_ConstraintTools::ComputeFix: nul plane" << endl;
1680 #endif
1681     NullifyAIS(anAIS);
1682     return;
1683   }
1684   //  Update de l'AIS
1685   Handle(AIS_FixRelation) ais;
1686   if (!anAIS.IsNull()) {
1687     ais = Handle(AIS_FixRelation)::DownCast(anAIS);
1688     if (ais.IsNull()) {
1689       ais = new AIS_FixRelation (shape1,aplane);
1690     }
1691     else {
1692       ais->SetFirstShape(shape1);
1693       ais->SetPlane(aplane);
1694     }
1695   }
1696   else ais = new AIS_FixRelation (shape1,aplane);
1697
1698   anAIS = ais;
1699 }
1700
1701 //=======================================================================
1702 //function : ComputeOffset
1703 //purpose  : 
1704 //=======================================================================
1705 void TPrsStd_ConstraintTools::ComputeOffset (const Handle(TDataXtd_Constraint)& aConst,
1706                                             Handle(AIS_InteractiveObject)& anAIS) 
1707 {
1708   // Get plane for planar constraint
1709   Standard_Boolean is_planar (aConst->IsPlanar());
1710   Handle(Geom_Plane) aplane;      
1711   if (is_planar) {
1712     GetGeom (aConst,aplane);
1713     if (aplane.IsNull()) {
1714 #ifdef DEB
1715       cout << "TPrsStd_ConstraintTools::ComputeOffset: null plane" << endl;
1716 #endif
1717       NullifyAIS(anAIS);
1718       return;
1719     }
1720   }
1721
1722   // Get shapes
1723   TopoDS_Shape S1, S2;
1724   Standard_Integer nbgeom = aConst->NbGeometries();
1725   if (nbgeom == 1) {
1726     Handle(TNaming_NamedShape) ageom1 = aConst->GetGeometry(1);
1727     // c'est une shape qui contient les faces generees par les faces d'origines
1728     TNaming_Iterator It (ageom1);
1729     if (It.More()) {
1730       S1 = It.OldShape();
1731       S2 = It.NewShape();
1732     }
1733   }
1734   else
1735   if (nbgeom == 2)  {
1736     // Get geometry of the constraint
1737     GetTwoShapes (aConst,S1,S2);
1738   }
1739
1740   if (S1.IsNull() || S2.IsNull()) {
1741 #ifdef DEB
1742     cout << "TPrsStd_ConstraintTools::ComputeOffset: null shape" << endl;
1743 #endif
1744     NullifyAIS(anAIS);
1745     return;
1746   }
1747
1748
1749   Standard_Real val1;
1750   TCollection_ExtendedString txt;
1751   Handle(AIS_LengthDimension) ais;
1752   //Handle(AIS_Drawer) aDrawer;
1753   Standard_Boolean NotNull = Standard_False;
1754
1755   if (nbgeom == 1) {
1756       
1757     ComputeTextAndValue (aConst,val1,txt,Standard_False);
1758   
1759     if (!anAIS.IsNull()) {
1760       ais = Handle(AIS_LengthDimension)::DownCast(anAIS);
1761       NotNull = Standard_True; 
1762     }
1763    
1764     if (S1.ShapeType() == TopAbs_FACE && S2.ShapeType() == TopAbs_FACE) {
1765       if (ais.IsNull()) {
1766         ais = new AIS_LengthDimension (TopoDS::Face(S1),TopoDS::Face(S2),
1767                                        val1,txt);
1768       }
1769       else {
1770         ais->SetFirstShape(S1);
1771         ais->SetSecondShape(S2);
1772         ais->SetValue(val1);
1773         ais->SetText(txt);
1774       }
1775
1776       if (is_planar) ais->SetPlane (aplane);
1777       anAIS = ais;
1778       return;
1779     }
1780     else
1781     if (S1.ShapeType() == TopAbs_EDGE && S2.ShapeType() == TopAbs_EDGE) {
1782       // Find a plane for the dimension
1783       TopoDS_Edge OE = TopoDS::Edge(S1);
1784       BRepAdaptor_Curve CURVE(OE);
1785       if (CURVE.GetType() == GeomAbs_Line)  {
1786         // Works only with line !!
1787 //#ifndef DEB
1788         Handle_Geom_Geometry aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1789         gp_Lin OLin = ((Handle(Geom_Line)&) aGeomGeometry)->Lin();
1790 //#else
1791 //      gp_Lin OLin = ((Handle(Geom_Line)&) CURVE.Curve().Curve()->Transformed(CURVE.Trsf()))->Lin();
1792 //#endif
1793         TopoDS_Edge NE = TopoDS::Edge(S2);
1794         CURVE.Initialize (NE);
1795 //#ifndef DEB
1796         aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1797         gp_Lin NLin = ((Handle(Geom_Line)&)aGeomGeometry)->Lin();
1798 //#else
1799 //      gp_Lin NLin = ((Handle(Geom_Line)&) CURVE.Curve().Curve()->Transformed(CURVE.Trsf()))->Lin();
1800 //#endif
1801         gp_Dir TDir (NLin.Location().XYZ() - OLin.Location().XYZ());
1802         aplane = new Geom_Plane (NLin.Location(),NLin.Direction()^TDir);
1803
1804         if (ais.IsNull()) {
1805           ais = new AIS_LengthDimension (S1,S2,aplane,val1,txt);
1806         }
1807         else {
1808           ais->SetFirstShape(S1);
1809           ais->SetSecondShape(S2);
1810           ais->SetValue(val1);
1811           ais->SetText(txt);
1812           ais->SetPlane(aplane);
1813         }
1814         anAIS = ais;
1815         return;
1816       }
1817       else
1818       if (CURVE.GetType() == GeomAbs_Circle)  {
1819 //#ifndef DEB
1820         Handle_Geom_Geometry aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1821         gp_Ax1 ax = ((Handle(Geom_Circle)&) aGeomGeometry)->Circ().Axis();
1822 //#else
1823 //      gp_Ax1 ax = ((Handle(Geom_Circle)&) CURVE.Curve().Curve()->Transformed(CURVE.Trsf()))->Circ().Axis();
1824 //#endif
1825         aplane = new Geom_Plane (ax.Location(),ax.Direction());
1826         is_planar = Standard_True;
1827       }
1828     }
1829   }
1830
1831
1832   if (!is_planar)  {
1833     if (S1.ShapeType() == TopAbs_COMPOUND && 
1834         S2.ShapeType() == TopAbs_COMPOUND)  {
1835       // Resultat d'un offset - on reconstruit un wire pour determiner un plan
1836       TopoDS_Wire w1;
1837       BRep_Builder B;
1838       B.MakeWire (w1);
1839       TopExp_Explorer exp (S1,TopAbs_EDGE);
1840       for (;exp.More();exp.Next())
1841         B.Add (w1,exp.Current());
1842
1843       BRepBuilderAPI_MakeFace MkF (w1,Standard_True);
1844       if (MkF.IsDone())  {
1845 //#ifndef DEB
1846         Handle_Geom_Surface aGeomSurface = BRep_Tool::Surface(MkF.Face());
1847         aplane = (Handle(Geom_Plane)&) aGeomSurface ;
1848 //#else
1849 //      aplane = ((Handle(Geom_Plane)&) BRep_Tool::Surface(MkF.Face()));
1850 //#endif
1851         is_planar = Standard_True;
1852       }
1853     }
1854   }
1855
1856   if (is_planar) {
1857     ComputeTextAndValue (aConst,val1,txt,Standard_False);
1858     TopExp_Explorer EXP1 (S1,TopAbs_VERTEX);
1859     S1 = EXP1.Current();
1860     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(S1));
1861       
1862     TopoDS_Vertex nearest;
1863     Standard_Real dist(RealLast());
1864
1865     for (TopExp_Explorer EXP2(S2,TopAbs_VERTEX); EXP2.More(); EXP2.Next()) {
1866       const TopoDS_Vertex& current = TopoDS::Vertex(EXP2.Current());
1867       gp_Pnt curpnt = BRep_Tool::Pnt(current);
1868       Standard_Real curdist = P.SquareDistance(curpnt);
1869       if (curdist < dist) {
1870         nearest= current;
1871         dist = curdist;
1872       }
1873     }
1874     S2 = nearest;
1875     if( !anAIS.IsNull() ) NotNull = Standard_True; 
1876     ais = Handle(AIS_LengthDimension)::DownCast(anAIS);
1877     if (ais.IsNull()) {
1878       ais = new AIS_LengthDimension (S1,S2,aplane,val1,txt);
1879     }
1880     else {
1881       ais->SetFirstShape (S1);
1882       ais->SetSecondShape (S2);
1883       ais->SetValue(val1);
1884       ais->SetText(txt);
1885       ais->SetPlane(aplane);
1886     }
1887     anAIS = ais;
1888     return;
1889   }
1890
1891 #ifdef DEB
1892   cout << "TPrsStd_ConstraintTools::ComputeOffset: Case not implemented" << endl;
1893 #endif
1894   NullifyAIS(anAIS);
1895 }
1896
1897
1898 //=======================================================================
1899 //function : ComputePlacement
1900 //purpose  : 
1901 //=======================================================================
1902 void TPrsStd_ConstraintTools::ComputePlacement
1903 (const Handle(TDataXtd_Constraint)& aConst,
1904  Handle(AIS_InteractiveObject)& anAIS) 
1905 {
1906   Standard_Integer nbgeom = aConst->NbGeometries();
1907   if (nbgeom < 2) 
1908     Standard_ProgramError::Raise
1909       ("TPrsStd_ConstraintTools::ComputePlacement: at leat two constraints are needed");
1910   
1911   TopoDS_Shape shape1,shape2 ;
1912   GetTwoShapes(aConst,shape1,shape2);
1913   if (shape1.IsNull() || shape2.IsNull()) {
1914 #ifdef DEB
1915     cout << "TPrsStd_ConstraintTools::ComputePlacement: nul shape" << endl;
1916 #endif
1917     NullifyAIS(anAIS);
1918     return;
1919   }
1920   
1921   Standard_Real val1=0.0;
1922   TCollection_ExtendedString txt= " ";
1923   if (aConst->IsDimension()) {
1924     ComputeTextAndValue(aConst,val1,txt,Standard_False);
1925   }
1926   //  Update de l'AIS
1927   Handle(AIS_OffsetDimension) ais;
1928   if (anAIS.IsNull()) {
1929     ais = new AIS_OffsetDimension(GetFace(shape1),GetFace(shape2),val1,txt);
1930     ais->SetArrowSize(val1/20.);
1931   } else {
1932     ais = Handle(AIS_OffsetDimension)::DownCast(anAIS);
1933     if (ais.IsNull()) {
1934       ais = new AIS_OffsetDimension(GetFace(shape1),GetFace(shape2),val1,txt);
1935       ais->SetArrowSize(val1/20.);
1936     } else {
1937       ais->SetFirstShape(GetFace(shape1));
1938       ais->SetSecondShape(GetFace(shape2));
1939       ais->SetValue(val1);
1940       ais->SetText(txt);
1941       ais->SetArrowSize(val1/20.);
1942     }
1943   }
1944   if (GetFace(shape1).IsNull() || GetFace(shape2).IsNull()) ais.Nullify();
1945   anAIS = ais;
1946 }
1947
1948 //=======================================================================
1949 //function : ComputeOthers
1950 //purpose  : 
1951 //=======================================================================
1952 void TPrsStd_ConstraintTools::ComputeOthers
1953 (const Handle(TDataXtd_Constraint)& aConst,
1954  Handle(AIS_InteractiveObject)& anAIS) 
1955 {
1956 }
1957
1958 //=======================================================================
1959 //function : GetOneShape
1960 //purpose  : 
1961 //=======================================================================
1962 void TPrsStd_ConstraintTools::GetOneShape
1963 (const Handle(TDataXtd_Constraint)& aConst,
1964  TopoDS_Shape& aShape) 
1965 {
1966   const Handle(TNaming_NamedShape)& ageom1 = aConst->GetGeometry(1);
1967   if (!ageom1.IsNull()) aShape =  TNaming_Tool::CurrentShape(ageom1);
1968 }
1969
1970 //=======================================================================
1971 //function : GetTwoShapes
1972 //purpose  : 
1973 //=======================================================================
1974 void TPrsStd_ConstraintTools::GetTwoShapes
1975 (const Handle(TDataXtd_Constraint)& aConst,
1976  TopoDS_Shape& aShape1,
1977  TopoDS_Shape& aShape2) 
1978 {
1979   const Handle(TNaming_NamedShape)& ageom1 = aConst->GetGeometry(1);    
1980   if (!ageom1.IsNull()) aShape1 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(1));
1981   const Handle(TNaming_NamedShape)& ageom2 = aConst->GetGeometry(2);    
1982   if (!ageom2.IsNull()) aShape2 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(2));
1983 }
1984
1985 //=======================================================================
1986 //function : GetShapesAndGeom
1987 //purpose  : 
1988 //=======================================================================
1989 void TPrsStd_ConstraintTools::GetShapesAndGeom
1990 (const Handle(TDataXtd_Constraint)& aConst,
1991  TopoDS_Shape& aShape1,
1992  TopoDS_Shape& aShape2,
1993  Handle(Geom_Geometry)& aGeom) 
1994 {
1995   GetTwoShapes(aConst,aShape1,aShape2);
1996   GetGeom(aConst,aGeom);
1997 }
1998
1999 //=======================================================================
2000 //function : GetShapesAndGeom
2001 //purpose  : 
2002 //=======================================================================
2003 void TPrsStd_ConstraintTools::GetShapesAndGeom
2004 (const Handle(TDataXtd_Constraint)& aConst,
2005  TopoDS_Shape& aShape1,
2006  TopoDS_Shape& aShape2,
2007  TopoDS_Shape& aShape3,
2008  Handle(Geom_Geometry)& aGeom) 
2009 {
2010   GetTwoShapes(aConst,aShape1,aShape2);
2011   const Handle(TNaming_NamedShape)& ageom3 = aConst->GetGeometry(3);//ota: GetGeometry(2) was  
2012   if (!ageom3.IsNull()) aShape3 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(3));
2013   GetGeom(aConst,aGeom);
2014 }
2015
2016 //=======================================================================
2017 //function : GetShapesAndGeom
2018 //purpose  : 
2019 //=======================================================================
2020 void TPrsStd_ConstraintTools::GetShapesAndGeom
2021   (const Handle(TDataXtd_Constraint)& aConst,
2022    TopoDS_Shape& aShape1,
2023    TopoDS_Shape& aShape2,
2024    TopoDS_Shape& aShape3,
2025    TopoDS_Shape& aShape4,
2026    Handle(Geom_Geometry)& aGeom) 
2027 {
2028   GetTwoShapes(aConst,aShape1, aShape2 );
2029   const Handle(TNaming_NamedShape)& ageom3 = aConst->GetGeometry(3);    
2030   if (!ageom3.IsNull()) aShape3 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(3));
2031   const Handle(TNaming_NamedShape)& ageom4 = aConst->GetGeometry(4); 
2032   if (!ageom4.IsNull()) aShape4 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(4));
2033   GetGeom(aConst,aGeom);
2034 }
2035
2036 //=======================================================================
2037 //function : ComputeCoincident
2038 //purpose  : 
2039 //=======================================================================
2040 void TPrsStd_ConstraintTools::ComputeCoincident(const Handle(TDataXtd_Constraint)& aConst,
2041                                                Handle(AIS_InteractiveObject)& anAIS) 
2042 {
2043   Standard_Integer nbgeom = aConst->NbGeometries();
2044   if (nbgeom < 2) {
2045 #ifdef DEB
2046     cout << "TPrsStd_ConstraintTools::ComputeCoincident: at leat two constraintes are needed" << endl;
2047 #endif
2048     NullifyAIS(anAIS);
2049     return; 
2050   }
2051   
2052   if (!aConst->IsPlanar()) { 
2053 #ifdef DEB
2054     cout << "TPrsStd_ConstraintTools::ComputeCoincident: must be a planar constraint" << endl;
2055 #endif
2056     anAIS.Nullify() ; 
2057     return;
2058   }
2059   
2060   TopoDS_Shape shape1,shape2 ;
2061   Handle(Geom_Plane) aplane;
2062   GetShapesAndGeom(aConst,shape1,shape2,aplane);
2063   if (shape1.IsNull() || shape2.IsNull()) {
2064 #ifdef DEB
2065     cout << "TPrsStd_ConstraintTools::ComputeCoincident: nul shape" << endl;
2066 #endif
2067     NullifyAIS(anAIS);
2068     return;
2069   }
2070
2071   GetGoodShape(shape1);
2072   GetGoodShape(shape2);
2073   if (aplane.IsNull()) {
2074 #ifdef DEB
2075     cout << "TPrsStd_ConstraintTools::ComputeCoincident: nul plane" << endl;
2076 #endif
2077     NullifyAIS(anAIS);
2078     return;
2079   }
2080   
2081   //  Update de l'AIS
2082   Handle(AIS_IdenticRelation) ais;
2083   if (anAIS.IsNull()) ais = new AIS_IdenticRelation(shape1,shape2,aplane);
2084   else {
2085     ais = Handle(AIS_IdenticRelation)::DownCast(anAIS);
2086     if (ais.IsNull()) {
2087       ais = new AIS_IdenticRelation(shape1,shape2,aplane);
2088     }
2089     else {
2090       ais->SetFirstShape(shape1);
2091       ais->SetSecondShape(shape2);
2092       ais->SetPlane(aplane);
2093     }
2094   }
2095   anAIS = ais;
2096 }
2097
2098 //=======================================================================
2099 //function : ComputeRound
2100 //purpose  : 
2101 //=======================================================================
2102 void TPrsStd_ConstraintTools::ComputeRound(const Handle(TDataXtd_Constraint)& aConst,
2103                                                Handle(AIS_InteractiveObject)& anAIS) 
2104 {
2105   Standard_Integer nbgeom = aConst->NbGeometries();
2106   if (nbgeom < 1) {
2107 #ifdef DEB
2108     cout << "TPrsStd_ConstraintTools::ComputeRound: at leat one geometry is needed" << endl;
2109 #endif
2110     NullifyAIS(anAIS);
2111     return; 
2112   }
2113   TopoDS_Shape shape1;
2114   GetOneShape (aConst,shape1);
2115   if (shape1.IsNull()) {
2116 #ifdef DEB
2117     cout << "TPrsStd_ConstraintTools::ComputePlacement: nul shape" << endl;
2118 #endif
2119     NullifyAIS(anAIS);
2120     return;
2121   }
2122   
2123   Standard_Real val1;
2124   TCollection_ExtendedString txt;
2125   ComputeTextAndValue(aConst,val1,txt,Standard_False);
2126   
2127   //  Update de l'AIS
2128   Handle(AIS_RadiusDimension) ais;
2129
2130   {
2131    try {
2132      OCC_CATCH_SIGNALS
2133      if (anAIS.IsNull()) ais = 
2134        new AIS_RadiusDimension(shape1,val1,txt);
2135      else {
2136        ais = Handle(AIS_RadiusDimension)::DownCast(anAIS);
2137        if (ais.IsNull()) {
2138          ais = new AIS_RadiusDimension(shape1,val1,txt);
2139        }
2140        else {
2141          ais->SetValue(val1);
2142          ais->SetText(txt);
2143          ais->SetFirstShape(shape1);
2144        }
2145      }
2146    }
2147    catch(Standard_Failure) {
2148      ais.Nullify();
2149    }
2150  }
2151   anAIS = ais;
2152 }
2153
2154 //=======================================================================
2155 //function : GetGeom
2156 //purpose  : 
2157 //=======================================================================
2158 void TPrsStd_ConstraintTools::GetGeom(const Handle(TDataXtd_Constraint)& aConst,
2159                                      Handle(Geom_Geometry)& aGeom)
2160 {  
2161   Handle(TNaming_NamedShape) atgeom = aConst->GetPlane();
2162   if (atgeom.IsNull()) {
2163 #ifdef DEB    
2164     cout<<"TPrsStd_ConstraintTools::GetGeom : aConst->GetPlane().IsNull()"<<endl;
2165 #endif
2166     return;
2167   }
2168   gp_Pln aplane;
2169   gp_Lin anaxis;
2170   gp_Pnt apoint;
2171   
2172   TDF_Label label = atgeom->Label();
2173
2174   Handle(TNaming_NamedShape) NS;
2175   if(label.FindAttribute(TNaming_NamedShape::GetID(),NS)){
2176     TopoDS_Shape s = TNaming_Tool::GetShape(NS);
2177     if(s.IsNull()) return;
2178   }
2179
2180   if (TDataXtd_Geometry::Plane(label,aplane)) aGeom =  new Geom_Plane(aplane);
2181   else if (TDataXtd_Geometry::Line(label,anaxis)) aGeom =  new Geom_Line(anaxis);
2182   else if (TDataXtd_Geometry::Point(label,apoint)) aGeom =  new Geom_CartesianPoint(apoint);
2183 #ifdef DEB
2184   else {
2185     cout << "TPrsStd_ConstraintTools::GetGeom no geom on label " << endl;
2186   }
2187 #endif  
2188 }
2189