//================================================================
// Function : drawVector
// Purpose  : displays a given vector in 3d viewer
//            (segment of line starting at thePnt with the arrow at the end,
//             the length of segment is the length of the vector)
//================================================================
Handle_AIS_InteractiveObject OCCDemo_Presentation::drawVector 
                                  (const gp_Pnt& thePnt,
                                   const gp_Vec& theVec,
                                   const Quantity_Color& theColor,
                                   const Standard_Boolean toDisplay)
{
  Standard_Real aLength = theVec.Magnitude();
  if (aLength < Precision::Confusion())
    return Handle(AIS_InteractiveObject)();

  Handle(Geom_Curve) aCurve = new Geom_Line (thePnt, theVec);
  aCurve = new Geom_TrimmedCurve (aCurve, 0, aLength);

  Handle(ISession_Curve) aGraphicCurve = new ISession_Curve (aCurve);

  getAISContext()->SetColor (aGraphicCurve, theColor, toDisplay);
  Handle(Prs3d_Drawer) aDrawer = aGraphicCurve->Attributes()->Link();
  aDrawer->SetLineArrowDraw(Standard_True);
  aDrawer->ArrowAspect()->SetLength(aLength/10);
  if (toDisplay) {
    if (FitMode){
		getAISContext()->Display (aGraphicCurve, Standard_False);
		COCCDemoDoc::Fit();
	}
	else
		getAISContext()->Display (aGraphicCurve);
  }

  return aGraphicCurve;
}
//================================================================
// Function : DrawSurface                           
// Purpose  : displays a given geometric surface in 3d viewer
//            (creates a finite face and displays it)
//================================================================
Handle_AIS_InteractiveObject OCCDemo_Presentation::drawSurface
                                  (const Handle_Geom_Surface& theSurface,
                                   const Quantity_Color& theColor,
                                   const Standard_Boolean toDisplay)
{
  Standard_Real u1, u2, v1, v2;
  theSurface->Bounds(u1,u2,v1,v2);
  fixParam(u1);
  fixParam(u2);
  fixParam(v1);
  fixParam(v2);

  Handle_AIS_Shape aGraphicSurface = 
    new AIS_Shape(BRepBuilderAPI_MakeFace (theSurface, u1, u2, v1, v2));

  getAISContext()->SetMaterial(aGraphicSurface, Graphic3d_NOM_PLASTIC, toDisplay);
  getAISContext()->SetColor(aGraphicSurface, theColor, toDisplay);
  if (toDisplay) {
    if (FitMode){
		getAISContext()->Display (aGraphicSurface, Standard_False);
		COCCDemoDoc::Fit();
	}
	else
		getAISContext()->Display (aGraphicSurface);
  }
  
  return aGraphicSurface;
}
//================================================================
// Function : drawPoint
// Purpose  : displays a given point
//================================================================
Handle_AIS_Point OCCDemo_Presentation::drawPoint
                                  (const gp_Pnt& aPnt,
                                   const Quantity_Color& theColor,
                                   const Standard_Boolean toDisplay)
{
  Handle(AIS_Point) aGraphicPoint = new AIS_Point (new Geom_CartesianPoint(aPnt));

  getAISContext()->SetColor (aGraphicPoint, theColor, toDisplay);
  if (toDisplay) {
    getAISContext()->Display (aGraphicPoint);
    //COCCDemoDoc::Fit();
  }

  return aGraphicPoint;
}
//================================================================
// Function : Convert_Presentation::sampleConicalSurface
// Purpose  : 
//================================================================
void Convert_Presentation::sampleConicalSurface()
{
  getAISContext()->EraseAll();

  Standard_CString aName = "Conical surface";
  TCollection_AsciiString aText (
    "  // creating an axis parallel to Z axis" EOL
    "  gp_Ax3 anAx(gp_Pnt(0,0,0), gp_Dir(0,0,1)); " EOL
    "  // creating a conical surface with base radius = 10 and angle = 20 deg" EOL
    "  Handle(Geom_ConicalSurface) aConicalSurface = new Geom_ConicalSurface(anAx,PI/9., 10);" EOL EOL

    "  // only finit surfaces can be converted to BSpline surfaces, " EOL
    "  // conical surface is infinite, it must be trimmed" EOL
    "  Handle(Geom_RectangularTrimmedSurface) aSurface = " EOL
    "    new Geom_RectangularTrimmedSurface(aConicalSurface, 0, 2*PI, -1000, 1000, Standard_True, Standard_True);" EOL);

  // creating an axis parallel to Z axis 
  gp_Ax3 anAx(gp_Pnt(0,0,0), gp_Dir(0,0,1)); 
  // creating a conical surface with base radius = 10 and angle = 20 deg
  Handle(Geom_ConicalSurface) aConicalSurface = new Geom_ConicalSurface(anAx,M_PI/9., 10);

  // only finit surfaces can be converted to BSpline surfaces, 
  // conical surface is infinite, it must be trimmed
  Handle(Geom_RectangularTrimmedSurface) aSurface = 
    new Geom_RectangularTrimmedSurface(aConicalSurface, 0, 2*M_PI, -1000, 1000, Standard_True, Standard_True);

  drawSurfaceAndItsBSpline(aSurface, aName, aText);
}
//================================================================
// Function : TexturesExt_Presentation::sampleBottle
// Purpose  : 
//================================================================
void TexturesExt_Presentation::sampleBottle()
{  
  TopoDS_Shape aShape;
  if (!loadShape(aShape, "bottle.brep")) 
    return;

  // resize and move the shape to the center of the viewer
gp_Trsf aTrsf1, aTrsf2;
aTrsf1.SetScale(gp_Pnt(0,0,0), 0.8);
aTrsf2.SetTranslation(gp_Pnt(0,0,0),gp_Pnt(0,0,-20));
aTrsf1.Multiply(aTrsf2);
BRepBuilderAPI_Transform Transformer(aTrsf1);
Transformer.Perform(aShape);
aShape = Transformer.Shape();

  TopTools_IndexedMapOfShape aFaces;
  TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);

  // display original shape in shaded display mode
  Handle_AIS_Shape aShapeIO = drawShape(aShape, Graphic3d_NOM_BRASS, Standard_False);
  getAISContext()->SetDisplayMode(aShapeIO, AIS_Shaded, Standard_False);
  // Set increased polygon offset for the main shape to avoid depth collision with textured faces
  aShapeIO->SetPolygonOffsets(Aspect_POM_Fill, 1.5, 0.5);
  DISP(aShapeIO);

  Handle_AIS_TexturedShape aTFace1 = Texturize(aFaces(16), "carrelage1.gif", 1, 1, 3, 2);
  DISP(aTFace1);

  Handle_AIS_TexturedShape aTFace2 = Texturize(aFaces(21), "carrelage1.gif", 1, 1, 3, 2);
  DISP(aTFace2);

  getViewer()->Update();
}
//================================================================
// Function : TexturesExt_Presentation::sampleLand
// Purpose  : 
//================================================================
void TexturesExt_Presentation::sampleTerrain()
{
  TopoDS_Shape aShape;
  if (!loadShape(aShape, "terrain.brep"))
    return;

  // a part of the landscape is textured
  TopTools_IndexedMapOfShape aFaces;
  TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);

//  TopLoc_Location aLoc;
//  Handle_Geom_Surface aSur = BRep_Tool::Surface(TopoDS::Face(aFaces(1)), aLoc);
//  Standard_Real u1,u2,v1,v2;
//  aSur->Bounds(u1,u2,v1,v2);
//  gp_Pnt aPnt = aSur->Value(u1, v1);
  gp_Pnt aPnt(82100,80300,10940);// point at u1,v1
  // resize and move the shape to the center of the viewer
  
  gp_Trsf aMoveTrsf;
  gp_Ax3 New(gp_Pnt(-30,-30, 0),gp_Dir(0,0,1));
  gp_Ax3 Current(aPnt,gp_Dir(0,0,1));
  aMoveTrsf.SetDisplacement(Current, New);

  gp_Trsf aScaleTrsf;
  aScaleTrsf.SetScale(aPnt,0.0075);

  BRepBuilderAPI_Transform aTransform(aMoveTrsf*aScaleTrsf);

  aTransform.Perform(aFaces(1));
  aShape = aTransform;

  getAISContext()->Display(Texturize(aShape, "terrain.gif"));
}
void Convert_Presentation::DoSample()
{
	((COCCDemoApp*) AfxGetApp())->SetSampleName("Convert");
	getAISContext()->EraseAll();
	if (myIndex >=0 && myIndex < myNbFuncs)
    (this->*SampleFuncs[myIndex])();
}
void Tesselate_Presentation::DoSample()
{
	((CTriangulationApp*) AfxGetApp())->SetSampleName("Tesselate");
	((CTriangulationApp*) AfxGetApp())->SetSamplePath("");
	getAISContext()->EraseAll();
	if (myIndex >=0 && myIndex < myNbSamples)
    sample (myFileNames[myIndex]);
}
Handle_AIS_Shape OCCDemo_Presentation::drawShape
         (const TopoDS_Shape& theShape,
          const Graphic3d_NameOfMaterial theMaterial,
          const Standard_Boolean toDisplay)
{
  Handle_AIS_Shape aGraphicShape = new AIS_Shape(theShape);

  getAISContext()->SetMaterial(aGraphicShape, theMaterial, toDisplay);
  if (toDisplay) {
    if (FitMode){
		getAISContext()->Display (aGraphicShape, Standard_False);
		COCCDemoDoc::Fit();
	}
	else
		getAISContext()->Display (aGraphicShape);
  }

  return aGraphicShape;
}
Handle_AIS_Shape OCCDemo_Presentation::drawShape 
         (const TopoDS_Shape& theShape,const Quantity_Color& theColor,
          const Standard_Boolean toDisplay)
{
  Handle_AIS_Shape aGraphicShape = new AIS_Shape(theShape);

  getAISContext()->SetMaterial(aGraphicShape, Graphic3d_NOM_PLASTIC, toDisplay);
  getAISContext()->SetColor (aGraphicShape, theColor, toDisplay);
  if (toDisplay){ 
    if (FitMode){
		getAISContext()->Display (aGraphicShape, Standard_False);
		COCCDemoDoc::Fit();
	}
	else
		getAISContext()->Display (aGraphicShape);
  }

  return aGraphicShape;
}
//================================================================
// Function : DrawCurve                                 
// Purpose  : displays a given curve 3d
//================================================================
Handle_AIS_InteractiveObject OCCDemo_Presentation::drawCurve
                                  (const Handle_Geom_Curve& theCurve,
                                   const Quantity_Color& theColor,
                                   const Standard_Boolean toDisplay)
{
  Handle(ISession_Curve) aGraphicCurve = new ISession_Curve (theCurve);

  getAISContext()->SetColor (aGraphicCurve, theColor, toDisplay);
  aGraphicCurve->Attributes()->Link()->SetLineArrowDraw(Standard_False);
  if (toDisplay){ 
    if (FitMode){
		getAISContext()->Display (aGraphicCurve, Standard_False);
		COCCDemoDoc::Fit();
	}
	else
		getAISContext()->Display (aGraphicCurve);
  }

  return aGraphicCurve;
}
void TexturesExt_Presentation::DoSample()
{
	((CViewer3dApp*) AfxGetApp())->SetSampleName("Viewer3d");
	((CViewer3dApp*) AfxGetApp())->SetSamplePath("..\\..\\04_Viewer3d");
	getAISContext()->EraseAll();
	if (myIndex >=0 && myIndex < myNbSamples)
	{
	  // turn lights on for terrain sample
	  lightsOnOff(myIndex==1);
	  (this->*SampleFuncs[myIndex])();
	}
}
//================================================================
// Function : OCCDemo_Presentation::sampleRevolSurface
// Purpose  : 
//================================================================
void Convert_Presentation::sampleRevolSurface()
{
  FitMode=false;
  ResetView();
  SetViewCenter(176.84682,102.12892);
  SetViewScale(0.69326);

  getAISContext()->EraseAll();

  Standard_CString aName = "Surface of revolution";
  TCollection_AsciiString aText (
    "  // creating a curve for revolution.  Let it be a Bezier curve." EOL
    "  Handle(Geom_BezierCurve) aBezierCurve;" EOL EOL

    "  // array of the bezier curve poles" EOL
    "  TColgp_Array1OfPnt aPoles(1,4);" EOL
    "  // array of the poles' weights" EOL
    "  TColStd_Array1OfReal aWeights(1,4);" EOL EOL

    "  aPoles(1) = gp_Pnt(0, 0, 0);      aWeights(1) = 1;" EOL
    "  aPoles(2) = gp_Pnt(150, 250, 0);  aWeights(2) =75;" EOL
    "  aPoles(3) = gp_Pnt(350, 150, 0);  aWeights(3) =120;" EOL
    "  aPoles(4) = gp_Pnt(500, 500, 0);  aWeights(4) = 1;" EOL EOL

    "  // creating a bezier curve" EOL
    "  aBezierCurve = new Geom_BezierCurve(aPoles, aWeights);" EOL EOL

    "  // creating a surface of revolution of the bezier curve around Y axis" EOL
    "  gp_Ax1 anAx(gp_Pnt(0, 0, 0), gp_Dir(0,1,0));" EOL
    "  Handle(Geom_SurfaceOfRevolution) aSurface = new Geom_SurfaceOfRevolution(aBezierCurve, anAx);" EOL
    );
  
  // array of the bezier curve poles
  TColgp_Array1OfPnt aPoles(1,4);
  // array of the poles' weights
  TColStd_Array1OfReal aWeights(1,4);

  aPoles(1) = gp_Pnt(0, 0, 0);      aWeights(1) = 1;
  aPoles(2) = gp_Pnt(150, 250, 0);  aWeights(2) =75;
  aPoles(3) = gp_Pnt(350, 150, 0);  aWeights(3) =120;
  aPoles(4) = gp_Pnt(500, 500, 0);  aWeights(4) = 1;

  Handle(Geom_BezierCurve) aBezierCurve = new Geom_BezierCurve(aPoles, aWeights);
  drawCurve(aBezierCurve);

  // creating a surface of revolution of the bezier curve around Y axis
  gp_Ax1 anAx(gp_Pnt(0,0,0), gp_Dir(0,1,0));
  Handle(Geom_SurfaceOfRevolution) aSurface = new Geom_SurfaceOfRevolution(aBezierCurve, anAx);

  drawSurfaceAndItsBSpline (aSurface, aName, aText);
  FitMode=true;
}
//================================================================
// Function : Convert_Presentation::sampleBezierSurface
// Purpose  : 
//================================================================
void Convert_Presentation::sampleBezierSurface()
{
  getAISContext()->EraseAll();

  Standard_CString aName = "BezierSurface";
  // Create a BezierSurface
  TColgp_Array2OfPnt aPoles(1,2,1,4); // 8 points
  TColStd_Array2OfReal aWeights(1,2,1,4);
  // initializing array of points
  aPoles.SetValue(1,1,gp_Pnt(0,10,0));     aPoles.SetValue(1,2,gp_Pnt(3.3,6.6,3));
  aPoles.SetValue(1,3,gp_Pnt(6.6,6.6,-3)); aPoles.SetValue(1,4,gp_Pnt(10,10,0));
  aPoles.SetValue(2,1,gp_Pnt(0,0,0));      aPoles.SetValue(2,2,gp_Pnt(3.3,3.3,-3));
  aPoles.SetValue(2,3,gp_Pnt(6.6,3.3,3));  aPoles.SetValue(2,4,gp_Pnt(10,0,0));  
  // scaling poles
  for (Standard_Integer i=1; i <= aPoles.ColLength(); i++)
    for (Standard_Integer j=1; j <= aPoles.RowLength(); j++)
      aPoles(i,j).ChangeCoord() = aPoles(i,j).Coord() * 100 + gp_XYZ(-500,-500,0);
  //initializing array of weights
  aWeights.SetValue(1,1,1); aWeights.SetValue(1,2,3);
  aWeights.SetValue(1,3,9); aWeights.SetValue(1,4,1);
  aWeights.SetValue(2,1,1); aWeights.SetValue(2,2,2);
  aWeights.SetValue(2,3,5); aWeights.SetValue(2,4,1);
  Handle(Geom_BezierSurface) aSurface =
    new Geom_BezierSurface(aPoles, aWeights);

  TCollection_AsciiString aText (
    "  // Create a BezierSurface" EOL
    "  TColgp_Array2OfPnt aPoles(1,2,1,4); // 8 points" EOL
    "  TColStd_Array2OfReal aWeights(1,2,1,4);" EOL
    "  // initializing array of points" EOL
    "  aPoles.SetValue(1,1,gp_Pnt(0,10,0));     aPoles.SetValue(1,2,gp_Pnt(3.3,6.6,3));" EOL
    "  aPoles.SetValue(1,3,gp_Pnt(6.6,6.6,-3)); aPoles.SetValue(1,4,gp_Pnt(10,10,0));" EOL
    "  aPoles.SetValue(2,1,gp_Pnt(0,0,0));      aPoles.SetValue(2,2,gp_Pnt(3.3,3.3,-3));" EOL
    "  aPoles.SetValue(2,3,gp_Pnt(6.6,3.3,3));  aPoles.SetValue(2,4,gp_Pnt(10,0,0));  " EOL
    "  // scaling poles" EOL
    "  for (Standard_Integer i=1; i <= aPoles.ColLength(); i++)" EOL
    "    for (Standard_Integer j=1; j <= aPoles.RowLength(); j++)" EOL
    "      aPoles(i,j).ChangeCoord() = aPoles(i,j).Coord() * 100 + gp_XYZ(-500,-500,0);" EOL
    "  //initializing array of weights" EOL
    "  aWeights.SetValue(1,1,1); aWeights.SetValue(1,2,3);" EOL
    "  aWeights.SetValue(1,3,9); aWeights.SetValue(1,4,1);" EOL
    "  aWeights.SetValue(2,1,1); aWeights.SetValue(2,2,2);" EOL
    "  aWeights.SetValue(2,3,5); aWeights.SetValue(2,4,1);" EOL
    "  Handle(Geom_BezierSurface) aSurface =" EOL
    "    new Geom_BezierSurface(aPoles, aWeights);" EOL
    );

  drawSurfaceAndItsBSpline (aSurface, aName, aText);
}
//================================================================
// Function : Convert_Presentation::sampleToroidalSurface
// Purpose  : 
//================================================================
void Convert_Presentation::sampleToroidalSurface()
{
  getAISContext()->EraseAll();

  Standard_CString aName = "Toroidal surface";
  TCollection_AsciiString aText (
    "  // creating an axis parallel to Y axis" EOL
    "  gp_Ax3 anAx(gp_Pnt(0,0,0), gp_Dir(0,1,0));" EOL
    "  // creating a toroidal surface with major radius = 240 and minor radius = 120" EOL
    "  Handle(Geom_ToroidalSurface) aSurface = new Geom_ToroidalSurface(anAx, 240, 120);" EOL);

  // creating an axis parallel to Y axis 
  gp_Ax3 anAx(gp_Pnt(0,0,0), gp_Dir(0,1,0)); 
  // creating a toroidal surface with major radius = 240 and minor radius = 120
  Handle(Geom_ToroidalSurface) aSurface = new Geom_ToroidalSurface(anAx, 240, 120);

  drawSurfaceAndItsBSpline(aSurface, aName, aText);
}
//================================================================
// Function : Convert_Presentation::sampleSphericalSurface
// Purpose  : 
//================================================================
void Convert_Presentation::sampleSphericalSurface()
{
  getAISContext()->EraseAll();

  Standard_CString aName = "Spherical surface";
  TCollection_AsciiString aText (
    "// creating an axis parallel to Z axis" EOL
    "gp_Ax3 anAx(gp_Pnt(0,0,0), gp_Dir(0,0,1));" EOL
    "// creating a spherical surface with radius = 300" EOL
    "Handle(Geom_SphericalSurface) aSurface = new Geom_SphericalSurface(anAx,300);" EOL);

  // creating an axis parallel to Z axis 
  gp_Ax3 anAx(gp_Pnt(0,0,0), gp_Dir(0,0,1)); 
  // creating a spherical surface with radius = 300
  Handle(Geom_SphericalSurface) aSurface = new Geom_SphericalSurface(anAx,300);

  drawSurfaceAndItsBSpline(aSurface, aName, aText);
}
void GeomConstraints_Presentation::DoSample()
{
  getAISContext()->EraseAll();
  if (myIndex >=0 && myIndex < myNbSamples)
    (this->*SampleFuncs[myIndex])();
}
void Tesselate_Presentation::tesselateShape(const TopoDS_Shape& aShape)
{
//  setResultTitle("Tesselate shape");
  TCollection_AsciiString aText = (
    "/////////////////////////////////////////////////////////////////" EOL
    "// Tesselate shape." EOL
    "/////////////////////////////////////////////////////////////////" EOL EOL
    ) ;

  Standard_Real aDeflection = DATA[myIndex][0];
  Standard_Integer aNumOfFace = (Standard_Integer)DATA[myIndex][1];
  Standard_Integer aNumOfEdge = (Standard_Integer)DATA[myIndex][2];

  aText +=
    "Standard_Real aDeflection;" EOL
    "// aDeflection = ... ;" EOL EOL

    "// removes all the triangulations of the faces ," EOL
    "//and all the polygons on the triangulations of the edges:" EOL
    "BRepTools::Clean(aShape);" EOL EOL

    "// adds a triangulation of the shape aShape with the deflection aDeflection:" EOL
    "BRepMesh::Mesh(aShape,aDeflection);" EOL EOL

    "TopExp_Explorer aExpFace,aExpEdge;" EOL
    "for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())" EOL
    "{  " EOL
    "  TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());" EOL
    "  TopLoc_Location aLocation;" EOL EOL
    
    "  // takes the triangulation of the face aFace:" EOL
    "  Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL EOL
    
    "  if(!aTr.IsNull()) // if this triangulation is not NULL" EOL
    "  { " EOL
    "    // takes the array of nodes for this triangulation:" EOL
    "    const TColgp_Array1OfPnt& aNodes = aTr->Nodes();" EOL
    "    // takes the array of triangles for this triangulation:" EOL
    "    const Poly_Array1OfTriangle& triangles = aTr->Triangles();" EOL EOL
    
    "    // create array of node points in absolute coordinate system" EOL
    "    TColgp_Array1OfPnt aPoints(1, aNodes.Length());" EOL
    "    for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)" EOL
    "      aPoints(i) = aNodes(i).Transformed(aLocation);" EOL EOL

    "    // Takes the node points of each triangle of this triangulation." EOL
    "    // takes a number of triangles:" EOL
    "    Standard_Integer nnn = aTr->NbTriangles();" EOL
    "    Standard_Integer nt,n1,n2,n3;" EOL
    "    for( nt = 1 ; nt < nnn+1 ; nt++)" EOL
    "    {" EOL
    "      // takes the node indices of each triangle in n1,n2,n3:" EOL
    "      triangles(nt).Get(n1,n2,n3);" EOL
    "      // takes the node points:" EOL
    "      gp_Pnt aPnt1 = aPoints(n1);" EOL
    "      gp_Pnt aPnt2 = aPoints(n2);" EOL
    "      gp_Pnt aPnt3 = aPoints(n3);" EOL
    "    } " EOL EOL
    
    "    // Takes the polygon associated to an edge." EOL
    "    aExpEdge.Init(aFace,TopAbs_EDGE);" EOL
    "    TopoDS_Edge aEdge;" EOL
    "    // for example,working with the first edge:" EOL
    "    if(aExpEdge.More())" EOL
    "      aEdge = TopoDS::Edge(aExpEdge.Current());" EOL EOL
    
    "    if(!aEdge.IsNull()) // if this edge is not NULL" EOL
    "    {" EOL
    "      // takes the polygon associated to the edge aEdge:" EOL
    "      Handle_Poly_PolygonOnTriangulation aPol = " EOL
    "        BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());" EOL EOL
    
    "      if(!aPol.IsNull()) // if this polygon is not NULL" EOL
    "        // takes the array of nodes for this polygon" EOL
    "        // (indexes in the array of nodes for triangulation of theFace):" EOL
    "        const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();" EOL
    "    }" EOL
    "  }" EOL
    "}" EOL EOL
    
    "//==================================================" EOL EOL
    
      ;
   aText += "  Result with deflection = ";
   aText += TCollection_AsciiString(aDeflection);
   aText += " :" EOL;

   GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//   setResultText(aText.ToCString());  

//==========================================================================

  BRepTools::Clean(aShape);
  BRepMesh::Mesh(aShape,aDeflection);

  BRep_Builder aBuilder,aBuild1,aBuild2;
  TopoDS_Compound aCompound,aComp1,aComp2;
  aBuilder.MakeCompound(aCompound);
  aBuild1.MakeCompound(aComp1);
  aBuild2.MakeCompound(aComp2);

  TopTools_SequenceOfShape aVertices;
  Standard_Integer aCount = 0;
  Standard_Integer aNumOfNodes = 0;
  Standard_Integer aNumOfTriangles = 0;
  
  Handle_AIS_InteractiveObject aShowEdge,aShowFace,aShowShape;
  
  TopExp_Explorer aExpFace,aExpEdge;

  for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())
  {  
    aCount++;
  
    TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
    TopLoc_Location aLocation;

    Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);

    if(!aTr.IsNull())
    { 
      const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
      aNumOfNodes += aTr->NbNodes();
      Standard_Integer aLower = aNodes.Lower();
      Standard_Integer anUpper = aNodes.Upper();
      const Poly_Array1OfTriangle& triangles = aTr->Triangles();
      aNumOfTriangles += aTr->NbTriangles();

      if(aCount == aNumOfFace)
      {
        Standard_Integer aNbOfNodesOfFace = aTr->NbNodes();
        Standard_Integer aNbOfTrianglesOfFace = aTr->NbTriangles();
        aExpEdge.Init(aFace,TopAbs_EDGE);

        TopoDS_Edge aEdge;

        for( Standard_Integer i = 0; aExpEdge.More() && i < aNumOfEdge ; aExpEdge.Next(), i++)
          aEdge = TopoDS::Edge(aExpEdge.Current());

        if(!aEdge.IsNull())
        {
          Handle_Poly_PolygonOnTriangulation aPol = 
            BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());

          if(!aPol.IsNull())
          {
            const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();
            Standard_Integer aNbOfNodesOfEdge = aPol->NbNodes();

            aText += "Number of nodes of the edge = ";
            aText += TCollection_AsciiString(aNbOfNodesOfEdge) + EOL;
            aText += "Number of nodes of the face = ";
            aText += TCollection_AsciiString(aNbOfNodesOfFace) + EOL;
            aText += "Number of triangles of the face = ";
            aText += TCollection_AsciiString(aNbOfTrianglesOfFace) + EOL;
			GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//            setResultText(aText.ToCString());  

            Standard_Integer aLower = aNodesOfPol.Lower(), anUpper = aNodesOfPol.Upper();
            for( int i = aLower; i < anUpper ; i++)
            {
              gp_Pnt aPnt1 = aNodes(aNodesOfPol(i)).Transformed(aLocation);
              gp_Pnt aPnt2 = aNodes(aNodesOfPol(i+1)).Transformed(aLocation);
              TopoDS_Vertex aVertex1 = BRepBuilderAPI_MakeVertex (aPnt1);
              TopoDS_Vertex aVertex2 = BRepBuilderAPI_MakeVertex (aPnt2);

              if(!aVertex1.IsNull() && !aVertex2.IsNull() && // if vertices are "alive"
                !BRep_Tool::Pnt(aVertex1).IsEqual(
                BRep_Tool::Pnt(aVertex2),Precision::Confusion())) // if they are different
              {
                aEdge = BRepBuilderAPI_MakeEdge (aVertex1,aVertex2);
                aBuild2.Add(aComp2,aVertex1);
                if(!aEdge.IsNull())
                  aBuild2.Add(aComp2,aEdge);
                if(i == anUpper-1)
                  aBuild2.Add(aComp2,aVertex2);
              }
            }
      
            getAISContext()->EraseAll();
            aShowShape = drawShape(aShape);
            if(WAIT_A_SECOND) return;
            aShowEdge = drawShape(aComp2,Quantity_NOC_GREEN);
            getAISContext()->Erase(aShowShape);
            if(WAIT_A_SECOND) return;
          }
        }
      }
    

      TopTools_DataMapOfIntegerShape aEdges;
      TopTools_SequenceOfShape aVertices;

      for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)
      {
        gp_Pnt aPnt = aNodes(i).Transformed(aLocation);
        TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(aPnt);

        if(!aVertex.IsNull())
        {
          aBuilder.Add(aCompound,aVertex);
          if(aCount == aNumOfFace ) 
            aBuild1.Add(aComp1,aVertex);
          aVertices.Append(aVertex);
        }
      }

      Standard_Integer nnn = aTr->NbTriangles();
      Standard_Integer nt,n1,n2,n3;

      for( nt = 1 ; nt < nnn+1 ; nt++)
      {     
        triangles(nt).Get(n1,n2,n3);

        Standard_Integer key[3];
        
        TopoDS_Vertex aV1,aV2;
        key[0] = _key(n1, n2);
        if(!aEdges.IsBound(key[0]))
        {
          aV1 = TopoDS::Vertex(aVertices(n1));
          aV2 = TopoDS::Vertex(aVertices(n2));
          if(!aV1.IsNull() && !aV2.IsNull() &&
            !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
          {
            TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
            if(!aEdge.IsNull())
            {
              aEdges.Bind(key[0], aEdge);
              aBuilder.Add(aCompound,aEdges(key[0]));
              if(aCount == aNumOfFace)
                aBuild1.Add(aComp1,aEdges(key[0]));
            } 
          }
        }
        
        key[1] = _key(n2,n3);
        if(!aEdges.IsBound(key[1])) 
        { 
          aV1 = TopoDS::Vertex(aVertices(n2));
          aV2 = TopoDS::Vertex(aVertices(n3));
          if(!aV1.IsNull() && !aV2.IsNull() &&
            !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
          {
            TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
            if(!aEdge.IsNull())
            {
              aEdges.Bind(key[1],aEdge);
              aBuilder.Add(aCompound,aEdges(key[1]));
              if(aCount == aNumOfFace) 
                aBuild1.Add(aComp1,aEdges(key[1]));
            } 
          } 
        } 
 
        key[2] = _key(n3,n1);
        if(!aEdges.IsBound(key[2])) 
        { 
          aV1 = TopoDS::Vertex(aVertices(n3));
          aV2 = TopoDS::Vertex(aVertices(n1));
          if(!aV1.IsNull() && !aV2.IsNull() &&
            !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
          { 
            TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
            if(!aEdge.IsNull())
            { 
              aEdges.Bind(key[2],aEdge);
              aBuilder.Add(aCompound,aEdges(key[2]));
              if(aCount == aNumOfFace) 
                aBuild1.Add(aComp1,aEdges(key[2]));
            } 
          } 
        } 
      } 
      
      if(aCount == aNumOfFace)
      {
        aShowFace = drawShape(aComp1,Quantity_NOC_GREEN);
        getAISContext()->Erase(aShowEdge);
      }
    }
    else
    {
      aText += "Can't compute a triangulation on face ";
      aText += TCollection_AsciiString(aCount) + EOL;
	  GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//      setResultText(aText.ToCString());
    }
  }
  
  aText += "Number of nodes of the shape = ";
  aText += TCollection_AsciiString(aNumOfNodes) + EOL;
  aText += "Number of triangles of the shape = ";
  aText += TCollection_AsciiString(aNumOfTriangles) + EOL EOL;
  GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//  setResultText(aText.ToCString());

  if(WAIT_A_SECOND) return;
  drawShape(aCompound,Quantity_NOC_GREEN);
  getAISContext()->Erase(aShowFace);
  
}
void Convert_Presentation::DoSample()
{
  getAISContext()->EraseAll();
  if (myIndex >=0 && myIndex < myNbFuncs)
    (this->*SampleFuncs[myIndex])();
}