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