Пример #1
0
bool OCC_Connect::CanMergeFace(TopoDS_Face face1,TopoDS_Face face2) const
{
    // FIXME, this really does not work.
    return 1;

    //double tol=1e-7;

    Handle(Geom_Surface) surface=BRep_Tool::Surface(face1);
    Standard_Real u1, u2, v1, v2;
    surface->Bounds(u1,u2,v1,v2);
    cout << "u1=" << u1 << " u2=" << u2 << " v1=" << v1 << " v2=" << v2 << endl;
    for(Standard_Real u=u1+(u2-u1)/10;u<u2;u+=(u2-u1)/10) {
        for(Standard_Real v=v1+(v2-v1)/10;v<v2;v+=(v2-v1)/10) {
            TopoDS_Vertex vtx=BRepBuilderAPI_MakeVertex(surface->Value(u,v));
            BRepExtrema_DistShapeShape dss(face2,vtx);
            dss.Perform();
#if 0
            double dist=dss.Value();
            if(dist>tol) {
                cout << "Distance=" << dist << " v=" << v << " u=" << u
                    << " pnt=" << surface->Value(u,v) << endl;
                BRepTools::Dump(face2,cout);
                return 0;
            }
#else
            dss.Dump(cout);
#endif
        }
    }
    return 1;
}
Пример #2
0
void AddVertex (double x, double y, double z, Handle_AIS_InteractiveContext theContext)
{
    TopoDS_Vertex aVertex=BRepBuilderAPI_MakeVertex( gp_Pnt(x,y,z) );
    Handle(AIS_Shape) AISVertex = new AIS_Shape(aVertex);
    // context is the handle to an AIS_InteractiveContext object.
    theContext->Display(AISVertex);
}
Пример #3
0
bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) {
	TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts];
	
	for ( int i = 0; i < numVerts; i ++ ) {
		gp_XY xy (verts[2*i],verts[2*i+1]);
		trsf.Transforms(xy);
		vertices[i] = BRepBuilderAPI_MakeVertex(gp_Pnt(xy.X(),xy.Y(),0.0f));
	}

	BRepBuilderAPI_MakeWire w;
	for ( int i = 0; i < numVerts; i ++ )
		w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts]));

	IfcGeom::convert_wire_to_face(w.Wire(),face);

	if ( numFillets && *std::max_element(filletRadii, filletRadii + numFillets) > 1e-7 ) {
		BRepFilletAPI_MakeFillet2d fillet (face);
		for ( int i = 0; i < numFillets; i ++ ) {
			const double radius = filletRadii[i];
			if ( radius <= 1e-7 ) continue;
			fillet.AddFillet(vertices[filletIndices[i]],radius);
		}
		fillet.Build();
		if (fillet.IsDone()) {
			face = TopoDS::Face(fillet.Shape());
		} else {
			Logger::Message(Logger::LOG_WARNING, "Failed to process profile fillets");
		}
	}

	delete[] vertices;
	return true;
}
Пример #4
0
bool OCC_Connect::CanMergeCurve(TopoDS_Edge edge1,TopoDS_Edge edge2) const
{
    if(BRep_Tool::Degenerated(edge1) && BRep_Tool::Degenerated(edge2))
        return 1;

    double tol=1e-7;

    Standard_Real s,e;
    Handle(Geom_Curve) curve=BRep_Tool::Curve(edge1,s,e);
    for(Standard_Real i=s;i<=e;i+=(e-s)/10) {
        TopoDS_Vertex v=BRepBuilderAPI_MakeVertex(curve->Value(i));
        double dist=BRepExtrema_DistShapeShape(edge2,v).Value();
        if(dist>tol)
            return 0;
    }
    return 1;
}
Пример #5
0
void occQt::makeRevol()
{
    gp_Ax1 anAxis;

    // revol a vertex result is an edge.
    anAxis.SetLocation(gp_Pnt(0.0, 70.0, 0.0));
    TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(gp_Pnt(2.0, 70.0, 0.0));
    TopoDS_Shape aRevolVertex = BRepPrimAPI_MakeRevol(aVertex, anAxis);
    Handle_AIS_Shape anAisRevolVertex = new AIS_Shape(aRevolVertex);

    // revol an edge result is a face.
    anAxis.SetLocation(gp_Pnt(8.0, 70.0, 0.0));
    TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(6.0, 70.0, 0.0), gp_Pnt(6.0, 70.0, 5.0));
    TopoDS_Shape aRevolEdge = BRepPrimAPI_MakeRevol(anEdge, anAxis);
    Handle_AIS_Shape anAisRevolEdge = new AIS_Shape(aRevolEdge);

    // revol a wire result is a shell.
    anAxis.SetLocation(gp_Pnt(20.0, 70.0, 0.0));
    anAxis.SetDirection(gp::DY());

    TopoDS_Edge aCircleEdge = BRepBuilderAPI_MakeEdge(gp_Circ(gp_Ax2(gp_Pnt(15.0, 70.0, 0.0), gp::DZ()), 1.5));
    TopoDS_Wire aCircleWire = BRepBuilderAPI_MakeWire(aCircleEdge);
    TopoDS_Shape aRevolCircle = BRepPrimAPI_MakeRevol(aCircleWire, anAxis, M_PI_2);
    Handle_AIS_Shape anAisRevolCircle = new AIS_Shape(aRevolCircle);

    // revol a face result is a solid.
    anAxis.SetLocation(gp_Pnt(30.0, 70.0, 0.0));
    anAxis.SetDirection(gp::DY());

    TopoDS_Edge aEllipseEdge = BRepBuilderAPI_MakeEdge(gp_Elips(gp_Ax2(gp_Pnt(25.0, 70.0, 0.0), gp::DZ()), 3.0, 2.0));
    TopoDS_Wire aEllipseWire = BRepBuilderAPI_MakeWire(aEllipseEdge);
    TopoDS_Face aEllipseFace = BRepBuilderAPI_MakeFace(gp_Pln(gp::XOY()), aEllipseWire);
    TopoDS_Shape aRevolEllipse = BRepPrimAPI_MakeRevol(aEllipseFace, anAxis, M_PI_4);
    Handle_AIS_Shape anAisRevolEllipse = new AIS_Shape(aRevolEllipse);

    anAisRevolVertex->SetColor(Quantity_NOC_LIMEGREEN);
    anAisRevolEdge->SetColor(Quantity_NOC_LINEN);
    anAisRevolCircle->SetColor(Quantity_NOC_MAGENTA1);
    anAisRevolEllipse->SetColor(Quantity_NOC_MAROON);

    mContext->Display(anAisRevolVertex);
    mContext->Display(anAisRevolEdge);
    mContext->Display(anAisRevolCircle);
    mContext->Display(anAisRevolEllipse);
}
Пример #6
0
void occQt::makeExtrude()
{
    // prism a vertex result is an edge.
    TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(gp_Pnt(0.0, 60.0, 0.0));
    TopoDS_Shape aPrismVertex = BRepPrimAPI_MakePrism(aVertex, gp_Vec(0.0, 0.0, 5.0));
    Handle_AIS_Shape anAisPrismVertex = new AIS_Shape(aPrismVertex);

    // prism an edge result is a face.
    TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(5.0, 60.0, 0.0), gp_Pnt(10.0, 60.0, 0.0));
    TopoDS_Shape aPrismEdge = BRepPrimAPI_MakePrism(anEdge, gp_Vec(0.0, 0.0, 5.0));
    Handle_AIS_Shape anAisPrismEdge = new AIS_Shape(aPrismEdge);

    // prism a wire result is a shell.
    gp_Ax2 anAxis;
    anAxis.SetLocation(gp_Pnt(16.0, 60.0, 0.0));

    TopoDS_Edge aCircleEdge = BRepBuilderAPI_MakeEdge(gp_Circ(anAxis, 3.0));
    TopoDS_Wire aCircleWire = BRepBuilderAPI_MakeWire(aCircleEdge);
    TopoDS_Shape aPrismCircle = BRepPrimAPI_MakePrism(aCircleWire, gp_Vec(0.0, 0.0, 5.0));
    Handle_AIS_Shape anAisPrismCircle = new AIS_Shape(aPrismCircle);

    // prism a face or a shell result is a solid.
    anAxis.SetLocation(gp_Pnt(24.0, 60.0, 0.0));
    TopoDS_Edge aEllipseEdge = BRepBuilderAPI_MakeEdge(gp_Elips(anAxis, 3.0, 2.0));
    TopoDS_Wire aEllipseWire = BRepBuilderAPI_MakeWire(aEllipseEdge);
    TopoDS_Face aEllipseFace = BRepBuilderAPI_MakeFace(gp_Pln(gp::XOY()), aEllipseWire);
    TopoDS_Shape aPrismEllipse = BRepPrimAPI_MakePrism(aEllipseFace, gp_Vec(0.0, 0.0, 5.0));
    Handle_AIS_Shape anAisPrismEllipse = new AIS_Shape(aPrismEllipse);

    anAisPrismVertex->SetColor(Quantity_NOC_PAPAYAWHIP);
    anAisPrismEdge->SetColor(Quantity_NOC_PEACHPUFF);
    anAisPrismCircle->SetColor(Quantity_NOC_PERU);
    anAisPrismEllipse->SetColor(Quantity_NOC_PINK);

    mContext->Display(anAisPrismVertex);
    mContext->Display(anAisPrismEdge);
    mContext->Display(anAisPrismCircle);
    mContext->Display(anAisPrismEllipse);
}
Пример #7
0
////////////////////////////////////////////////////////////////////////////////
// Construct TopoDS from BRL-CAD data
////////////////////////////////////////////////////////////////////////////////
BRLTopo::BRLTopo(struct rt_arb_internal *arb)
{
    TopoDS_Vertex v[8];
    for(int i=0;i<8;i++)
        v[i]=BRepBuilderAPI_MakeVertex(
            gp_Pnt(
                scale*arb->pt[i][0],
                scale*arb->pt[i][1],
                scale*arb->pt[i][2]
            )
        );

    int arbn;
    if(!BRepTools::Compare(v[6],v[7]))
        arbn=8;
    else if(!BRepTools::Compare(v[4],v[5]))
        arbn=7;
    else if(!BRepTools::Compare(v[5],v[6]))
        arbn=6;
    else if(!BRepTools::Compare(v[0],v[3]))
        arbn=5;
    else
        arbn=4;

    switch(arbn) {
    case 8: {
        TopoDS_Edge e[12];
        for(int i=0;i<4;i++) { 
            e[i]=BRepBuilderAPI_MakeEdge(v[i],v[(i+1)%4]);
            e[i+4]=BRepBuilderAPI_MakeEdge(v[i+4],v[(i+1)%4+4]);
            e[i+8]=BRepBuilderAPI_MakeEdge(v[i],v[(i+4)%8]);
        }

        TopoDS_Wire w[6];
        w[0]=BRepBuilderAPI_MakeWire(e[0],e[1],e[2],e[3]);
        w[1]=BRepBuilderAPI_MakeWire(e[4],e[5],e[6],e[7]);
        w[2]=BRepBuilderAPI_MakeWire(e[0],e[9],e[4],e[8]);
        w[3]=BRepBuilderAPI_MakeWire(e[1],e[10],e[5],e[9]);
        w[4]=BRepBuilderAPI_MakeWire(e[2],e[11],e[6],e[10]);
        w[5]=BRepBuilderAPI_MakeWire(e[3],e[8],e[7],e[11]);

        BRep_Builder BB;
        TopoDS_Shell shell;
        BB.MakeShell(shell);
        for(int i=0;i<6;i++) {
            TopoDS_Face f=BRepBuilderAPI_MakeFace(w[i]);
            BB.Add(shell,i? f.Reversed():f);
        }
        TopoDS_Solid solid;
        BB.MakeSolid(solid);
        BB.Add(solid,shell);
        ShapeFix_Solid sf(solid);
        sf.Perform();
        shape=sf.Solid();
        } break;
    case 6: {
        TopoDS_Edge e[9];
        e[0]=BRepBuilderAPI_MakeEdge(v[0],v[1]);
        e[1]=BRepBuilderAPI_MakeEdge(v[1],v[2]);
        e[2]=BRepBuilderAPI_MakeEdge(v[2],v[3]);
        e[3]=BRepBuilderAPI_MakeEdge(v[3],v[0]);
        e[4]=BRepBuilderAPI_MakeEdge(v[0],v[4]);
        e[5]=BRepBuilderAPI_MakeEdge(v[1],v[4]);
        e[6]=BRepBuilderAPI_MakeEdge(v[2],v[6]);
        e[7]=BRepBuilderAPI_MakeEdge(v[3],v[6]);
        e[8]=BRepBuilderAPI_MakeEdge(v[4],v[6]);

        TopoDS_Wire w[5];
        w[0]=BRepBuilderAPI_MakeWire(e[0],e[1],e[2],e[3]);
        w[1]=BRepBuilderAPI_MakeWire(e[0],e[4],e[5]);
        w[2]=BRepBuilderAPI_MakeWire(e[2],e[6],e[7]);
        w[3]=BRepBuilderAPI_MakeWire(e[3],e[4],e[8],e[7]);
        w[4]=BRepBuilderAPI_MakeWire(e[1],e[5],e[8],e[6]);

        BRep_Builder BB;
#if 0
        TopoDS_Compound result;
        BB.MakeCompound(result);
        for(int i=0;i<5;i++) {
            BB.Add(result,BRepBuilderAPI_MakeFace(w[i]));
        }
        shape=result;
#else
        TopoDS_Shell shell;
        BB.MakeShell(shell);
        for(int i=0;i<5;i++) {
            TopoDS_Face f=BRepBuilderAPI_MakeFace(w[i]);
            BB.Add(shell,f); //i? f:f.Reversed());
        }
        TopoDS_Solid solid;
        BB.MakeSolid(solid);
        BB.Add(solid,shell);
        ShapeFix_Solid sf(solid);
        sf.Perform();
        shape=sf.Solid();
#endif
        } break;
    default:
        cerr << "Unhandled arb8 type n=" << arbn << '\n';
    }
}
Пример #8
0
//=======================================================================
//function : MakeScaledPrism
//purpose  :
//=======================================================================
TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShapeBase,
                                                    const gp_Vec&       theVector,
                                                    const Standard_Real theScaleFactor,
                                                    const gp_Pnt&       theCDG,
                                                    bool                isCDG)
{
  TopoDS_Shape aShape;
  BRep_Builder B;

  // 1. aCDG = geompy.MakeCDG(theBase)
  gp_Pnt aCDG = theCDG;
  if (!isCDG) {
    gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase);
    aCDG = aPos.Location();
  }
  TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape();

  // Process case of several given shapes
  if (theShapeBase.ShapeType() == TopAbs_COMPOUND ||
      theShapeBase.ShapeType() == TopAbs_SHELL) {
    int nbSub = 0;
    TopoDS_Shape aShapeI;
    TopoDS_Compound aCompound;
    B.MakeCompound(aCompound);
    TopoDS_Iterator It (theShapeBase, Standard_True, Standard_True);
    for (; It.More(); It.Next()) {
      nbSub++;
      aShapeI = MakeScaledPrism(It.Value(), theVector, theScaleFactor, aCDG, true);
      B.Add(aCompound, aShapeI);
    }
    if (nbSub == 1)
      aShape = aShapeI;
    else if (nbSub > 1)
      aShape = GEOMImpl_GlueDriver::GlueFaces(aCompound, Precision::Confusion(), Standard_True);
    return aShape;
  }

  // 2. Scale = geompy.MakeScaleTransform(theBase, aCDG, theScaleFactor)

  // Bug 6839: Check for standalone (not included in faces) degenerated edges
  TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
  TopExp::MapShapesAndAncestors(theShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
  Standard_Integer i, nbE = aEFMap.Extent();
  for (i = 1; i <= nbE; i++) {
    TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
    if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
      const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
      if (aFaces.IsEmpty())
        Standard_ConstructionError::Raise
          ("Scaling aborted : cannot scale standalone degenerated edge");
    }
  }

  // Perform Scaling
  gp_Trsf aTrsf;
  aTrsf.SetScale(aCDG, theScaleFactor);
  BRepBuilderAPI_Transform aBRepTrsf (theShapeBase, aTrsf, Standard_False);
  TopoDS_Shape aScale = aBRepTrsf.Shape();

  // 3. aBase2 = geompy.MakeTranslationVectorDistance(Scale, theVec, theH)
  gp_Trsf aTrsf3;
  aTrsf3.SetTranslation(theVector);
  TopLoc_Location aLocOrig = aScale.Location();
  gp_Trsf aTrsfOrig = aLocOrig.Transformation();
  TopLoc_Location aLocRes (aTrsf3 * aTrsfOrig);
  TopoDS_Shape aBase2 = aScale.Located(aLocRes);

  // 4. aCDG_2 = geompy.MakeTranslationVectorDistance(aCDG, theVec, theH)
  gp_Pnt aCDG_2 = aCDG.Translated(theVector);
  TopoDS_Shape aShapeCDG_2 = BRepBuilderAPI_MakeVertex(aCDG_2).Shape();

  // 5. Vector = geompy.MakeVector(aCDG, aCDG_2)
  TopoDS_Shape aShapeVec = BRepBuilderAPI_MakeEdge(aCDG, aCDG_2).Shape();
  TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
  TopoDS_Wire aWirePath = BRepBuilderAPI_MakeWire(anEdge);

  // 6. aPrism = geompy.MakePipeWithDifferentSections([theBase, aBase2], [aCDG, aCDG_2], Vector, False, False)
  Handle(TopTools_HSequenceOfShape) aBases = new TopTools_HSequenceOfShape;
  aBases->Append(theShapeBase);
  aBases->Append(aBase2);

  Handle(TopTools_HSequenceOfShape) aLocs = new TopTools_HSequenceOfShape;
  aLocs->Append(aShapeCDG_1);
  aLocs->Append(aShapeCDG_2);

  aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections(aWirePath, aBases, aLocs, false, false);

  // 7. Make a solid, if possible
  if (theShapeBase.ShapeType() == TopAbs_FACE) {
    BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0);
    TopExp_Explorer expF (aShape, TopAbs_FACE);
    Standard_Integer ifa = 0;
    for (; expF.More(); expF.Next()) {
      aSewing.Add(expF.Current());
      ifa++;
    }
    if (ifa > 0) {
      aSewing.Perform();
      TopoDS_Shape aShell;

      TopoDS_Shape sh = aSewing.SewedShape();
      if (sh.ShapeType() == TopAbs_FACE && ifa == 1) {
        // case for creation of shell from one face
        TopoDS_Shell ss;
        B.MakeShell(ss);
        B.Add(ss,sh);
        aShell = ss;
      }
      else {
        TopExp_Explorer exp (sh, TopAbs_SHELL);
        Standard_Integer ish = 0;
        for (; exp.More(); exp.Next()) {
          aShell = exp.Current();
          ish++;
        }
        if (ish != 1)
          aShell = sh;
      }
      BRepCheck_Shell chkShell (TopoDS::Shell(aShell));
      if (chkShell.Closed() == BRepCheck_NoError) {
        TopoDS_Solid Sol;
        B.MakeSolid(Sol);
        B.Add(Sol, aShell);
        BRepClass3d_SolidClassifier SC (Sol);
        SC.PerformInfinitePoint(Precision::Confusion());
        if (SC.State() == TopAbs_IN) {
          B.MakeSolid(Sol);
          B.Add(Sol, aShell.Reversed());
        }
        aShape = Sol;
      }
    }
  }

  return aShape;
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
	IfcSchema::IfcCurve* basis_curve = l->BasisCurve();
	bool isConic = basis_curve->is(IfcSchema::Type::IfcConic);
	double parameterFactor = isConic ? getValue(GV_PLANEANGLE_UNIT) : getValue(GV_LENGTH_UNIT);
	Handle(Geom_Curve) curve;
	if ( !convert_curve(basis_curve,curve) ) return false;
	bool trim_cartesian = l->MasterRepresentation() == IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
	IfcEntityList::ptr trims1 = l->Trim1();
	IfcEntityList::ptr trims2 = l->Trim2();
	bool trimmed1 = false;
	bool trimmed2 = false;
	unsigned sense_agreement = l->SenseAgreement() ? 0 : 1;
	double flts[2];
	gp_Pnt pnts[2];
	bool has_flts[2] = {false,false};
	bool has_pnts[2] = {false,false};
	BRepBuilderAPI_MakeWire w;
	for ( IfcEntityList::it it = trims1->begin(); it != trims1->end(); it ++ ) {
		IfcUtil::IfcBaseClass* i = *it;
		if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
			IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[sense_agreement] );
			has_pnts[sense_agreement] = true;
		} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
			const double value = *((IfcSchema::IfcParameterValue*)i);
			flts[sense_agreement] = value * parameterFactor;
			has_flts[sense_agreement] = true;
		}
	}
	for ( IfcEntityList::it it = trims2->begin(); it != trims2->end(); it ++ ) {
		IfcUtil::IfcBaseClass* i = *it;
		if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
			IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[1-sense_agreement] );
			has_pnts[1-sense_agreement] = true;
		} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
			const double value = *((IfcSchema::IfcParameterValue*)i);
			flts[1-sense_agreement] = value * parameterFactor;
			has_flts[1-sense_agreement] = true;
		}
	}
	trim_cartesian &= has_pnts[0] && has_pnts[1];
	bool trim_cartesian_failed = !trim_cartesian;
	if ( trim_cartesian ) {
		if ( pnts[0].Distance(pnts[1]) < getValue(GV_WIRE_CREATION_TOLERANCE) ) {
			Logger::Message(Logger::LOG_WARNING,"Skipping segment with length below tolerance level:",l->entity);
			return false;
		}
		ShapeFix_ShapeTolerance FTol;
		TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(pnts[0]);
		TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(pnts[1]);
		FTol.SetTolerance(v1, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
		FTol.SetTolerance(v2, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
		BRepBuilderAPI_MakeEdge e (curve,v1,v2);
		if ( ! e.IsDone() ) {
			BRepBuilderAPI_EdgeError err = e.Error();
			if ( err == BRepBuilderAPI_PointProjectionFailed ) {
				Logger::Message(Logger::LOG_WARNING,"Point projection failed for:",l->entity);
				trim_cartesian_failed = true;
			}
		} else {
			w.Add(e.Edge());
		}
	}
	if ( (!trim_cartesian || trim_cartesian_failed) && (has_flts[0] && has_flts[1]) ) {
		// The Geom_Line is constructed from a gp_Pnt and gp_Dir, whereas the IfcLine
		// is defined by an IfcCartesianPoint and an IfcVector with Magnitude. Because
		// the vector is normalised when passed to Geom_Line constructor the magnitude
		// needs to be factored in with the IfcParameterValue here.
		if ( basis_curve->is(IfcSchema::Type::IfcLine) ) {
			IfcSchema::IfcLine* line = static_cast<IfcSchema::IfcLine*>(basis_curve);
			const double magnitude = line->Dir()->Magnitude();
			flts[0] *= magnitude; flts[1] *= magnitude;
		}
		if ( basis_curve->is(IfcSchema::Type::IfcEllipse) ) {
			IfcSchema::IfcEllipse* ellipse = static_cast<IfcSchema::IfcEllipse*>(basis_curve);
			double x = ellipse->SemiAxis1() * getValue(GV_LENGTH_UNIT);
			double y = ellipse->SemiAxis2() * getValue(GV_LENGTH_UNIT);
			const bool rotated = y > x;
			if (rotated) {
				flts[0] -= M_PI / 2.;
				flts[1] -= M_PI / 2.;
			}
		}
		if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],(double)(M_PI*2.0)),0.0f) ) {
			w.Add(BRepBuilderAPI_MakeEdge(curve));
		} else {
			BRepBuilderAPI_MakeEdge e (curve,flts[0],flts[1]);
			w.Add(e.Edge());
		}			
	} else if ( trim_cartesian_failed && (has_pnts[0] && has_pnts[1]) ) {
		w.Add(BRepBuilderAPI_MakeEdge(pnts[0],pnts[1]));
	}
	if ( w.IsDone() ) {
		wire = w.Wire();
		return true;
	} else {
		return false;
	}
}
Пример #10
0
int main(int argc, char **args)
{
    // Create a sphere
    gp_Pnt center(0, 0, 0);
    Standard_Real radius = 100;

    TopoDS_Shape sphere =
        BRepPrimAPI_MakeSphere(
            center, radius
        ).Shape();

    // Save it in STL, STEP and IGES
    saveInSTL(sphere, "shape.stl");
    assert(saveInSTEP(sphere, "shape.stp"));
    assert(saveInIGES(sphere, "shape.igs"));

    // Load the sphere from the files
    TopoDS_Shape shape_from_stl = openSTL("shape.stl");
    TopoDS_Shape shape_from_step = openSTEP("shape.stp");
    TopoDS_Shape shape_from_iges = openIGES("shape.igs");

    bool inside;
    clock_t stl_speed = 0;
    clock_t step_speed = 0;
    clock_t iges_speed = 0;
    Standard_Real count_points = 0;

    for (Standard_Real x = -(radius/2); x <= (radius/2); x += (radius/5)) {
        for (Standard_Real y = -(radius/2); y <= (radius/2); y += (radius/5)) {
            for (Standard_Real z = -(radius/2); z <= (radius/2); z += (radius/5)) {
                count_points++;

                TopoDS_Vertex vertex =
                    BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, z)).Vertex();

                Standard_Real expected_distance = fabs(sqrt(
                        pow(center.X() - x, 2) +
                        pow(center.Y() - y, 2) +
                        pow(center.Z() - z, 2))
                                                       - radius);

                clock_t t = clock();
                Standard_Real distance = distanceTwoShapes(shape_from_stl, vertex, inside);
                stl_speed += clock() - t;

                assert(almost_equal(distance, expected_distance, 0.3));

                t = clock();
                distance = distanceTwoShapes(shape_from_step, vertex, inside);
                step_speed += clock() - t;

                // don't check if inside
                if (!inside) {
                    assert(almost_equal(distance, expected_distance, 0.0001));
                }

                t = clock();
                distance = distanceTwoShapes(shape_from_iges, vertex, inside);
                iges_speed += clock() - t;

                assert(almost_equal(distance, expected_distance, 0.0001));
            }
        }
    }

    stl_speed /= count_points;
    step_speed /= count_points;
    iges_speed /= count_points;

    cout << "STL average speed: " << stl_speed << " ticks" << endl;
    cout << "STEP average speed: " << step_speed << " ticks" << endl;
    cout << "IGES average speed: " << iges_speed << " ticks" << endl;

    return 0;
}
Пример #11
0
//=======================================================================
// profile
// command to build a profile
//=======================================================================
Sketcher_Profile::Sketcher_Profile(const char* aCmd)
{
  enum {line, circle, point, none} move;

  Standard_Integer i = 1;
  Standard_Real x0, y0, x, y, dx, dy;
  x0 = y0 = x = y = dy = 0;
  dx = 1;

  Standard_Boolean first, stayfirst, face, close;
  first = Standard_True;
  stayfirst = face = close = Standard_False;

  Standard_Integer reversed = 0;
  Standard_Integer control_Tolerance = 0;

  TopoDS_Shape S;
  TopoDS_Vertex MP;
  BRepBuilderAPI_MakeWire MW;
  gp_Ax3 DummyHP(gp::XOY());
  gp_Pln P(DummyHP);
  TopLoc_Location TheLocation;
  Handle(Geom_Surface) Surface;

  myOK = Standard_False;
  myError = 0;

  //TCollection_AsciiString aCommand(CORBA::string_dup(aCmd));
  TCollection_AsciiString aCommand ((char*)aCmd);
  TCollection_AsciiString aToken = aCommand.Token(":", 1);
  int n = 0;
  // porting to WNT
  TColStd_Array1OfAsciiString aTab (0, aCommand.Length() - 1);
  if ( aCommand.Length() )
  {
    while(aToken.Length() != 0) {
      if(aCommand.Token(":", n + 1).Length() > 0)
        aTab(n) = aCommand.Token(":", n + 1);
      aToken = aCommand.Token(":", ++n);
    }
    n = n - 1;
  }
  if ( aTab.Length() && aTab(0).Length() )
    while(i < n) {
      Standard_Real length = 0, radius = 0, angle = 0;
      move = point;

      int n1 = 0;
      TColStd_Array1OfAsciiString a (0, aTab(0).Length());
      aToken = aTab(i).Token(" ", 1);
      while (aToken.Length() != 0) {
        if (aTab(i).Token(" ", n1 + 1).Length() > 0)
          a(n1) = aTab(i).Token(" ", n1 + 1);
        aToken = aTab(i).Token(" ", ++n1);
      }
      n1 = n1 - 1;

      switch(a(0).Value(1))
      {
      case 'F':
        {
          if (n1 != 3) goto badargs;
          if (!first) {
            MESSAGE("profile : The F instruction must precede all moves");
            return;
          }
          x0 = x = a(1).RealValue();
          y0 = y = a(2).RealValue();
          stayfirst = Standard_True;
          break;
        }
      case 'O':
        {
          if (n1 != 4) goto badargs;
          P.SetLocation(gp_Pnt(a(1).RealValue(), a(2).RealValue(), a(3).RealValue()));
          stayfirst = Standard_True;
          break;
        }
      case 'P':
        {
          if (n1 != 7) goto badargs;
          gp_Vec vn(a(1).RealValue(), a(2).RealValue(), a(3).RealValue());
          gp_Vec vx(a(4).RealValue(), a(5).RealValue(), a(6).RealValue());
          if (vn.Magnitude() <= Precision::Confusion() || vx.Magnitude() <= Precision::Confusion()) {
            MESSAGE("profile : null direction");
            return;
          }
          gp_Ax2 ax(P.Location(), vn, vx);
          P.SetPosition(ax);
          stayfirst = Standard_True;
          break;
        }
      case 'X':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "XX")
            length -= x;
          dx = 1; dy = 0;
          move = line;
          break;
        }
      case 'Y':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "YY")
            length -= y;
          dx = 0; dy = 1;
          move = line;
          break;
        }
      case 'L':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (Abs(length) > Precision::Confusion())
            move = line;
          else
            move = none;
          break;
        }
      case 'T':
        {
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          if (a(0) == "TT") {
            vx -= x;
            vy -= y;
          }
          length = Sqrt(vx * vx + vy * vy);
          if (length > Precision::Confusion()) {
            move = line;
            dx = vx / length;
            dy = vy / length;
          }
          else
            move = none;
          break;
        }
      case 'R':
        {
          if (n1 != 2) goto badargs;
          angle = a(1).RealValue() * PI180;
          if (a(0) == "RR") {
            dx = Cos(angle);
            dy = Sin(angle);
          }
          else {
            Standard_Real c = Cos(angle);
            Standard_Real s = Sin(angle);
            Standard_Real t = c * dx - s * dy;
            dy = s * dx + c * dy;
            dx = t;
          }
          break;
        }
      case 'D':
        {
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          length = Sqrt(vx * vx + vy * vy);
          if (length > Precision::Confusion()) {
            dx = vx / length;
            dy = vy / length;
          }
          else
            move = none;
          break;
        }
      case 'C':
        {
          if (n1 != 3) goto badargs;
          radius = a(1).RealValue();
          if (Abs(radius) > Precision::Confusion()) {
            angle = a(2).RealValue() * PI180;
            move = circle;
          }
          else
            move = none;
          break;
        }
      case 'A':                                // TAngential arc by end point   
        { 
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue(); 
          if (a(0) == "AA") {
            vx -= x;
            vy -= y;
          }
          Standard_Real det = dx * vy - dy * vx;
          if ( Abs(det) > Precision::Confusion()) {
            Standard_Real c = (dx * vx + dy * vy)                                            
                              / Sqrt((dx * dx + dy * dy) * (vx * vx + vy * vy));                 // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi]
            radius = (vx * vx + vy * vy)* Sqrt(dx * dx + dy * dy)                                // radius = distance between start and end point / 2 * sin(alpha)  
                     / (2.0 * det);	                                                             // radius is > 0 or < 0
            if (Abs(radius) > Precision::Confusion()) {
              angle = 2.0 * acos(c); 	                                                         // angle in [0,2Pi]  
              move = circle;
            }
            else
              move = none;
            break;
          } 
          else
            move = none;
          break;
        } 
      case 'U':                                // Arc by end point and radiUs
        { 
          if (n1 != 5) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          radius  = a(3).RealValue();
          reversed = a(4).IntegerValue();
          if (a(0) == "UU") {                 // Absolute
            vx -= x;
            vy -= y;
          }
          Standard_Real length = Sqrt(vx * vx + vy * vy);
          if ( (4.0 - (vx * vx + vy * vy) / (radius * radius) >= 0.0 ) && (length > Precision::Confusion()) ) {
            Standard_Real c = 0.5 * Sqrt(4.0 - (vx * vx + vy * vy) / (radius * radius));        // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2]
            angle = 2.0 * acos(c); 	                                                            // angle in [0,Pi]
            if ( reversed == 2 )
              angle = angle - 2 * PI; 
            dx =    0.5 * (  vy * 1.0/radius 
                           + vx * Sqrt(4.0  / (vx * vx + vy * vy) - 1.0 / (radius * radius)));    
            dy = -  0.5 * (  vx * 1.0/radius 
                           - vy * Sqrt(4.0  / (vx * vx + vy * vy) - 1.0 / (radius * radius)));    
            move = circle;
          }
          else{
            move = none;
          }
          break;
        }	 
      case 'E':                                // Arc by end point and cEnter
        { 
          if (n1 != 7) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          Standard_Real vxc  = a(3).RealValue();
          Standard_Real vyc  = a(4).RealValue();
          reversed = a(5).IntegerValue();
          control_Tolerance = a(6).IntegerValue();

          if (a(0) == "EE") {                 // Absolute
            vx -= x;
            vy -= y;
            vxc -= x;
            vyc -= y; 
          }
          radius = Sqrt( vxc * vxc + vyc * vyc );
          Standard_Real det = vx * vyc - vy * vxc;
          Standard_Real length = Sqrt(vx * vx + vy * vy);
          Standard_Real length2 = Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc));
          Standard_Real length3 = Sqrt(vxc * vxc + vyc * vyc);
          Standard_Real error = Abs(length2 - radius);
          myError = error;
          if ( error > Precision::Confusion() ){
            MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error);
          }
          if ( error > Precision::Confusion() && control_Tolerance == 1)                      // Don't create the arc if the end point 
            move = none;                                                                      // is too far from it
          else if ( (length > Precision::Confusion()) && 
                    (length2 > Precision::Confusion()) && 
                    (length3 > Precision::Confusion()) ) {
            Standard_Real c = ( radius * radius - (vx * vxc + vy * vyc) ) 
                            / ( radius * Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc)) ) ;  // Cosine of arc angle 
            angle = acos(c);                                                                  // angle in [0,Pi] 
            if ( reversed == 2 )
              angle = angle - 2 * PI;
            if (det < 0)
              angle = -angle; 
            dx =  vyc / radius;
            dy = -vxc / radius; 
            move = circle;
          }
          else {
            move = none;
          }
          break;
        }	
      case 'I':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "IX") {
            if (Abs(dx) < Precision::Confusion()) {
              MESSAGE("profile : cannot intersect, arg "<<i-1);
              return;
            }
            length = (length - x) / dx;
          }
          else if (a(0) == "IY") {
            if (Abs(dy) < Precision::Confusion()) {
              MESSAGE("profile : cannot intersect, arg "<<i-1);
              return;
            }
            length = (length - y) / dy;
          }
          if (Abs(length) > Precision::Confusion())
            move = line;
          else
            move = none;
          break;
        }
      case 'W':
        {
          if (a(0) == "WW")
            close = Standard_True;
          else if(a(0) == "WF") {
            close = Standard_True;
            face = Standard_True;
          }
          i = n - 1;
          break;
        }
      default:
        {
          MESSAGE("profile : unknown code " << a(i));
          return;
        }
    }

again :
    switch (move)
    {
    case line :
      {
        if (length < 0) {
          length = -length;
          dx = -dx;
          dy = -dy;
        }
        Handle(Geom2d_Line) l = new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy));
        BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(l,P),0,length);
        if (!ME.IsDone())
          return;
        MW.Add(ME);
        x += length*dx;
        y += length*dy;
        break;
      }
    case circle :
      {
        Standard_Boolean sense = Standard_True;
        if (radius < 0) {
          radius = -radius;
          sense = !sense;
          dx = -dx;
          dy = -dy;
        }
        gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx));
        if (angle < 0) {
          angle = -angle;
          sense = !sense;
        }
        Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense);
        BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(c,P),0,angle);
        if (!ME.IsDone())
          return;
        MW.Add(ME);
        gp_Pnt2d p;
        gp_Vec2d v;
        c->D1(angle,p,v);
        x = p.X();
        y = p.Y();
        dx = v.X() / radius;
        dy = v.Y() / radius;
        break;
      }
    case point:
      {
        MP = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0));
        break;
      }
    case none:
      {
        i = n - 1;
        break;
      }
    }

    // update first
    first = stayfirst;
    stayfirst = Standard_False;

    if(!(dx == 0 && dy == 0))
      myLastDir.SetCoord(dx, dy, 0.0);
    else
      return;
    myLastPoint.SetX(x);
    myLastPoint.SetY(y);

    // next segment....
    i++;
    if ((i == n) && close) {
      // the closing segment
      dx = x0 - x;
      dy = y0 - y;
      length = Sqrt(dx * dx + dy * dy);
      move = line;
      if (length > Precision::Confusion()) {
        dx = dx / length;
        dy = dy / length;
        goto again;
      }
    }
  }

  // get the result, face or wire
  if (move == none) {
    return;
  } else if (move == point) {
    S = MP;
  } else if (face) {
    if (!MW.IsDone()) {
      return;
    }
    BRepBuilderAPI_MakeFace MF (P, MW.Wire());
    if (!MF.IsDone()) {
      return;
    }
    S = MF;
  } else {
    if (!MW.IsDone()) {
      return;
    }
    S = MW;
  }

  if(!TheLocation.IsIdentity())
    S.Move(TheLocation);

  myShape = S;
  myOK = true;
  return;

  badargs :
    MESSAGE("profile : bad number of arguments");
    return;
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IMeasure aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == CDG_MEASURE)
  {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Shape for centre of mass calculation is null");
    }

    gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aShapeBase);
    gp_Pnt aCenterMass = aPos.Location();
    aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
  }
  else if (aType == VERTEX_BY_INDEX)
  {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Shape for centre of mass calculation is null");
    }

    int index = aCI.GetIndex();
    gp_Pnt aVertex;

    if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
      if ( index != 1 )
        Standard_NullObject::Raise("Vertex index is out of range");
      else
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase));
    } else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
      TopoDS_Vertex aV1, aV2;
      TopoDS_Edge anEdgeE = TopoDS::Edge(aShapeBase);
      
      TopExp::Vertices(anEdgeE, aV1, aV2);
      gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
      gp_Pnt aP2 = BRep_Tool::Pnt(aV2);

      if (index < 0 || index > 1)
        Standard_NullObject::Raise("Vertex index is out of range");

      if ( ( anEdgeE.Orientation() == TopAbs_FORWARD && index == 0 ) ||
           ( anEdgeE.Orientation() == TopAbs_REVERSED && index == 1 ) )
        aVertex = aP1;
      else
      aVertex = aP2;
    } else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
      TopTools_IndexedMapOfShape anEdgeShapes;
      TopTools_IndexedMapOfShape aVertexShapes;
      TopoDS_Vertex aV1, aV2;
      TopoDS_Wire aWire = TopoDS::Wire(aShapeBase);
      TopExp_Explorer exp (aWire, TopAbs_EDGE);
      for (; exp.More(); exp.Next()) {
        anEdgeShapes.Add(exp.Current());
        TopoDS_Edge E = TopoDS::Edge(exp.Current());
        TopExp::Vertices(E, aV1, aV2);
        if ( aVertexShapes.Extent() == 0)
          aVertexShapes.Add(aV1);
        if ( !aV1.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
          aVertexShapes.Add(aV1);
        if ( !aV2.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
          aVertexShapes.Add(aV2);
      }

      if (index < 0 || index > aVertexShapes.Extent())
        Standard_NullObject::Raise("Vertex index is out of range");

      if (aWire.Orientation() == TopAbs_FORWARD)
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(index+1)));
      else
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(aVertexShapes.Extent() - index)));
    } else {
      Standard_NullObject::Raise("Shape for vertex calculation is not an edge or wire");
    }

    aShape = BRepBuilderAPI_MakeVertex(aVertex).Shape();
  }
  else if (aType == VECTOR_FACE_NORMALE)
  {
    // Face
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Face for normale calculation is null");
    }
    if (aShapeBase.ShapeType() != TopAbs_FACE) {
      Standard_NullObject::Raise("Shape for normale calculation is not a face");
    }
    TopoDS_Face aFace = TopoDS::Face(aShapeBase);

    // Point
    gp_Pnt p1 (0,0,0);

    Handle(GEOM_Function) aPntFunc = aCI.GetPoint();
    if (!aPntFunc.IsNull())
    {
      TopoDS_Shape anOptPnt = aPntFunc->GetValue();
      if (anOptPnt.IsNull())
        Standard_NullObject::Raise("Invalid shape given for point argument");
      p1 = BRep_Tool::Pnt(TopoDS::Vertex(anOptPnt));
    }
    else
    {
      gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aFace);
      p1 = aPos.Location();
    }

    // Point parameters on surface
    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
    Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf);
    gp_Pnt2d pUV = aSurfAna->ValueOfUV(p1, Precision::Confusion());

    // Normal direction
    gp_Vec Vec1,Vec2;
    BRepAdaptor_Surface SF (aFace);
    SF.D1(pUV.X(), pUV.Y(), p1, Vec1, Vec2);
    if (Vec1.Magnitude() < Precision::Confusion()) {
      gp_Vec tmpV;
      gp_Pnt tmpP;
      SF.D1(pUV.X(), pUV.Y()-0.1, tmpP, Vec1, tmpV);
    }
    else if (Vec2.Magnitude() < Precision::Confusion()) {
      gp_Vec tmpV;
      gp_Pnt tmpP;
      SF.D1(pUV.X()-0.1, pUV.Y(), tmpP, tmpV, Vec2);
    }

    gp_Vec V = Vec1.Crossed(Vec2);
    Standard_Real mod = V.Magnitude();
    if (mod < Precision::Confusion())
      Standard_NullObject::Raise("Normal vector of a face has null magnitude");

    // Set length of normal vector to average radius of curvature
    Standard_Real radius = 0.0;
    GeomLProp_SLProps aProperties (aSurf, pUV.X(), pUV.Y(), 2, Precision::Confusion());
    if (aProperties.IsCurvatureDefined()) {
      Standard_Real radius1 = Abs(aProperties.MinCurvature());
      Standard_Real radius2 = Abs(aProperties.MaxCurvature());
      if (Abs(radius1) > Precision::Confusion()) {
        radius = 1.0 / radius1;
        if (Abs(radius2) > Precision::Confusion()) {
          radius = (radius + 1.0 / radius2) / 2.0;
        }
      }
      else {
        if (Abs(radius2) > Precision::Confusion()) {
          radius = 1.0 / radius2;
        }
      }
    }

    // Set length of normal vector to average dimension of the face
    // (only if average radius of curvature is not appropriate)
    if (radius < Precision::Confusion()) {
        Bnd_Box B;
        Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
        BRepBndLib::Add(aFace, B);
        B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
        radius = ((Xmax - Xmin) + (Ymax - Ymin) + (Zmax - Zmin)) / 3.0;
    }

    if (radius < Precision::Confusion())
      radius = 1.0;

    V *= radius / mod;

    // consider the face orientation
    if (aFace.Orientation() == TopAbs_REVERSED ||
        aFace.Orientation() == TopAbs_INTERNAL) {
      V = - V;
    }

    // Edge
    gp_Pnt p2 = p1.Translated(V);
    BRepBuilderAPI_MakeEdge aBuilder (p1, p2);
    if (!aBuilder.IsDone())
      Standard_NullObject::Raise("Vector construction failed");
    aShape = aBuilder.Shape();
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;
}
Пример #13
0
bool IfcGeom::convert(const Ifc2x3::IfcTrimmedCurve::ptr l, TopoDS_Wire& wire) {
	Ifc2x3::IfcCurve::ptr basis_curve = l->BasisCurve();
	bool isConic = basis_curve->is(Ifc2x3::Type::IfcConic);
	double parameterFactor = isConic ? IfcGeom::GetValue(GV_PLANEANGLE_UNIT) : IfcGeom::GetValue(GV_LENGTH_UNIT);
	Handle(Geom_Curve) curve;
	if ( ! IfcGeom::convert_curve(basis_curve,curve) ) return false;
	bool trim_cartesian = l->MasterRepresentation() == Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
	IfcUtil::IfcAbstractSelect::list trims1 = l->Trim1();
	IfcUtil::IfcAbstractSelect::list trims2 = l->Trim2();
	bool trimmed1 = false;
	bool trimmed2 = false;
	unsigned sense_agreement = l->SenseAgreement() ? 0 : 1;
	double flts[2];
	gp_Pnt pnts[2];
	bool has_flts[2] = {false,false};
	bool has_pnts[2] = {false,false};
	BRepBuilderAPI_MakeWire w;
	for ( IfcUtil::IfcAbstractSelect::it it = trims1->begin(); it != trims1->end(); it ++ ) {
		const IfcUtil::IfcAbstractSelect::ptr i = *it;
		if ( i->is(Ifc2x3::Type::IfcCartesianPoint) ) {
			IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcCartesianPoint>(i), pnts[sense_agreement] );
			has_pnts[sense_agreement] = true;
		} else if ( i->is(Ifc2x3::Type::IfcParameterValue) ) {
			const double value = *reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcUtil::IfcArgumentSelect>(i)->wrappedValue();
			flts[sense_agreement] = value * parameterFactor;
			has_flts[sense_agreement] = true;
		}
	}
	for ( IfcUtil::IfcAbstractSelect::it it = trims2->begin(); it != trims2->end(); it ++ ) {
		const IfcUtil::IfcAbstractSelect::ptr i = *it;
		if ( i->is(Ifc2x3::Type::IfcCartesianPoint) ) {
			IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcCartesianPoint>(i), pnts[1-sense_agreement] );
			has_pnts[1-sense_agreement] = true;
		} else if ( i->is(Ifc2x3::Type::IfcParameterValue) ) {
			const double value = *reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcUtil::IfcArgumentSelect>(i)->wrappedValue();
			flts[1-sense_agreement] = value * parameterFactor;
			has_flts[1-sense_agreement] = true;
		}
	}
	trim_cartesian &= has_pnts[0] && has_pnts[1];
	bool trim_cartesian_failed = !trim_cartesian;
	if ( trim_cartesian ) {
		if ( pnts[0].Distance(pnts[1]) < GetValue(GV_WIRE_CREATION_TOLERANCE) ) {
			Logger::Message(Logger::LOG_WARNING,"Skipping segment with length below tolerance level:",l->entity);
			return false;
		}
		ShapeFix_ShapeTolerance FTol;
		TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(pnts[0]);
		TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(pnts[1]);
		FTol.SetTolerance(v1, GetValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
		FTol.SetTolerance(v2, GetValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
		BRepBuilderAPI_MakeEdge e (curve,v1,v2);
		if ( ! e.IsDone() ) {
			BRepBuilderAPI_EdgeError err = e.Error();
			if ( err == BRepBuilderAPI_PointProjectionFailed ) {
				Logger::Message(Logger::LOG_WARNING,"Point projection failed for:",l->entity);
				trim_cartesian_failed = true;
			}
		} else {
			w.Add(e.Edge());
		}
	}
	if ( (!trim_cartesian || trim_cartesian_failed) && (has_flts[0] && has_flts[1]) ) {
		if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],(double)(M_PI*2.0)),0.0f) ) {
			w.Add(BRepBuilderAPI_MakeEdge(curve));
		} else {
			BRepBuilderAPI_MakeEdge e (curve,flts[0],flts[1]);
			w.Add(e.Edge());
		}			
	} else if ( trim_cartesian_failed && (has_pnts[0] && has_pnts[1]) ) {
		w.Add(BRepBuilderAPI_MakeEdge(pnts[0],pnts[1]));
	}
	if ( w.IsDone() ) {
		wire = w.Wire();
		return true;
	} else {
		return false;
	}
}
Пример #14
0
void OCC_Connect::Intersect(BRep_Builder &BB, TopoDS_Shape &target,
    TopoDS_Shape &shape, TopoDS_Shape &tool)
{
    /***************************************************************************
        We start by splitting edges at all the edge-edge intersections.
        This may generate new vertices and edges.
    ***************************************************************************/
    MergeVertices(shape,tool);
    LocOpe_SplitShape splitter1(shape);
    LocOpe_SplitShape splitter2(tool);
    TopOpeBRep_ShapeIntersector intersector;
    for(intersector.InitIntersection(shape,tool);
        intersector.MoreIntersection();
        intersector.NextIntersection()
    ) {
        if(verbose&Cutting) {
            cout << "++++++++++++++++++++++++++++++++++++++++"
                "++++++++++++++++++++++++++++++++++++++++\n";
            intersector.DumpCurrent(1); cout << " --> ";
            intersector.DumpCurrent(2); cout << '\n';
        }

        TopOpeBRep_EdgesIntersector &ee=intersector.ChangeEdgesIntersector();
        if( intersector.CurrentGeomShape(1).ShapeType()==TopAbs_EDGE &&
            intersector.CurrentGeomShape(2).ShapeType()==TopAbs_EDGE
        ) {
            for(ee.InitPoint(); ee.MorePoint(); ee.NextPoint()) {
                TopOpeBRep_Point2d const &p=ee.Point();
                if(verbose&Cutting)
                    cout << "point loop " << p.Parameter(1) << '\n';
                TopoDS_Vertex vertex;
                if(p.IsVertex(1))
                    vertex=p.Vertex(1);
                else if(p.IsVertex(2))
                    vertex=p.Vertex(2);
                else
                    vertex=BRepBuilderAPI_MakeVertex(p.Value());
                if(!p.IsVertex(1)) {
                    TopoDS_Edge edge=TopoDS::Edge(ee.Edge(1));
                    if(!splitter1.CanSplit(edge)) {
                        if(verbose&Cutting)
                            cout << "Cannot split 1\n";;
                    } else {
                        if(verbose&Cutting)
                            cout << "splitting model 1\n";
                        try { splitter1.Add(vertex,p.Parameter(1),edge); }
                        catch(Standard_ConstructionError c) {
                            if(verbose&Cutting)
                                cout << "Ooops \n";
                        }
                    }
                }
                if(!p.IsVertex(2)) {
                    TopoDS_Edge edge=TopoDS::Edge(ee.Edge(2));
                    if(!splitter2.CanSplit(edge)) {
                        if(verbose&Cutting)
                            cout << "Cannot split 2\n";;
                    } else {
                        if(verbose&Cutting)
                            cout << "splitting model 2\n";
                        try { splitter2.Add(vertex,p.Parameter(2),edge); }
                        catch(Standard_ConstructionError c) {
                            if(verbose&Cutting)
                                cout << "Ooops \n";
                        }
                    }
                }
            }
        }
    }

    /***************************************************************************
        Not all intersections seem to be caught, this is an attempt to catch
        some missing intersections. FIXME, this is almost certainly incomplete.
    ***************************************************************************/
    TopTools_IndexedMapOfShape edges, faces, vertices;
    vertices.Clear();
    TopExp::MapShapes(shape,TopAbs_VERTEX,vertices);
    TopExp::MapShapes(tool,TopAbs_VERTEX,vertices);

    edges.Clear();
    TopExp::MapShapes(shape,TopAbs_EDGE,edges);
    for(int e=1; e<=edges.Extent(); e++) {
        TopoDS_Edge edge=TopoDS::Edge(edges(e));
        TopoDS_Vertex o1, o2;
        TopExp::Vertices(edge,o1,o2);
        int skip1=vertices.FindIndex(o1);
        int skip2=vertices.FindIndex(o2);
        for(int v=1; v<=vertices.Extent(); v++) {
            if(v==skip1 || v==skip2)
                continue;
            TopoDS_Vertex vertex=TopoDS::Vertex(vertices(v));
            BRepExtrema_ExtPC distance(vertex,edge);
            if(!distance.IsDone())
                continue;
            double tolerance=std::max(BRep_Tool::Tolerance(edge),
                                      BRep_Tool::Tolerance(vertex));
            for(int i=1;i<=distance.NbExt();i++) {
#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
              double value = distance.Value(i);
#else
              double value = distance.SquareDistance(i);
#endif
              if(value<tolerance) {
                    try {
                        // No idea why this can fail
                        splitter1.Add(vertex,distance.Parameter(i),edge);
                    }
                    catch(Standard_ConstructionError c) {
                        if(verbose&Cutting) {
                            cout << "Adding vertex to edge failed\n";
                            TopoDS_Vertex v1, v2;
                            TopExp::Vertices(edge,v1,v2);
                            if(BRepTools::Compare(v1,vertex))
                                cout << "Merge v1\n";
                            if(BRepTools::Compare(v2,vertex))
                                cout << "Merge v2\n";
                            double d1=BRep_Tool::Pnt(v1).Distance(
                                BRep_Tool::Pnt(vertex));
                            double d2=BRep_Tool::Pnt(v2).Distance(
                                BRep_Tool::Pnt(vertex));
                            cout << "Adding " << i << " to edge " << e
                                << " distance=" << value
                                << " parameter=" << distance.Parameter(i)
                                << " point=" << distance.Point(i)
                                << " dv1=" << d1
                                << " dv2=" << d2
                                << endl;
                            BRepTools::Dump(vertex,cout);
                            BRepTools::Dump(edge,cout);
                        }
                    }
                }
            }
        }
    }

    edges.Clear();
    TopExp::MapShapes(tool,TopAbs_EDGE,edges);
    for(int e=1; e<=edges.Extent(); e++) {
        TopoDS_Edge edge=TopoDS::Edge(edges(e));
        TopoDS_Vertex o1, o2;
        TopExp::Vertices(edge,o1,o2);
        int skip1=vertices.FindIndex(o1);
        int skip2=vertices.FindIndex(o2);
        for(int v=1; v<=vertices.Extent(); v++) {
            if(v==skip1 || v==skip2)
                continue;
            TopoDS_Vertex vertex=TopoDS::Vertex(vertices(v));
            BRepExtrema_ExtPC distance(vertex,edge);
            if(!distance.IsDone())
                continue;
            double tolerance=std::max(BRep_Tool::Tolerance(edge),
                                      BRep_Tool::Tolerance(vertex));
            for(int i=1;i<=distance.NbExt();i++) {
#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
              double value = distance.Value(i);
#else
              double value = distance.SquareDistance(i);
#endif
              if(value<tolerance) {
                    try {
                        splitter2.Add(vertex,distance.Parameter(i),edge);
                    }
                    catch(Standard_ConstructionError c) {
                        if(verbose&Cutting) {
                            cout << "Adding vertex to edge failed\n";
                            TopoDS_Vertex v1, v2;
                            TopExp::Vertices(edge,v1,v2);
                            if(BRepTools::Compare(v1,vertex))
                                cout << "Merge v1\n";
                            if(BRepTools::Compare(v2,vertex))
                                cout << "Merge v2\n";
                            double d1=BRep_Tool::Pnt(v1).Distance(
                                BRep_Tool::Pnt(vertex));
                            double d2=BRep_Tool::Pnt(v2).Distance(
                                BRep_Tool::Pnt(vertex));
                            cout << "Adding " << i << " to edge " << e
                                << " distance=" << value
                                << " parameter=" << distance.Parameter(i)
                                << " point=" << distance.Point(i)
                                << " dv1=" << d1
                                << " dv2=" << d2
                                << endl;
                            BRepTools::Dump(vertex,cout);
                            BRepTools::Dump(edge,cout);
                        }
                    }
                }
            }
        }
    }

    /***************************************************************************
        We need the shapes with all the edge-edge intersections to split
        all the faces. All vertices and edges which can be merged, will
        be merged.
    ***************************************************************************/
    TopoDS_Compound intermediate1;
    BB.MakeCompound(intermediate1);
    for(TopTools_ListIteratorOfListOfShape p(splitter1.DescendantShapes(shape));
        p.More();
        p.Next()
    ) {
        BB.Add(intermediate1,p.Value());
    }
    TopoDS_Compound intermediate2;
    BB.MakeCompound(intermediate2);
    for(TopTools_ListIteratorOfListOfShape p(splitter2.DescendantShapes(tool));
        p.More();
        p.Next()
    ) {
        BB.Add(intermediate2,p.Value());
    }
    if(verbose&Cutting) {
        cout << "Before merging vertices and edges\n";
        TopoDS_Compound t;
        BB.MakeCompound(t);
        BB.Add(t,intermediate1);
        BB.Add(t,intermediate2);
        PrintItemCount(t);
    }
    MergeVertices(intermediate1,intermediate2);
    MergeEdges(intermediate1,intermediate2);
    if(verbose&Cutting) {
        cout << "After merging vertices and edges\n";
        TopoDS_Compound t;
        BB.MakeCompound(t);
        BB.Add(t,intermediate1);
        BB.Add(t,intermediate2);
        PrintItemCount(t);
    }

    // Create the result
    TopoDS_Compound result;
    BB.MakeCompound(result);
    BB.Add(result,intermediate1);
    BB.Add(result,intermediate2);

    // Add any missing PCurves
    for(TopExp_Explorer face(result,TopAbs_FACE); face.More(); face.Next()) {
        for(TopExp_Explorer edge(face.Current(),TopAbs_EDGE);
            edge.More();
            edge.Next()
        ) {
            Standard_Real s, e;
            TopoDS_Edge c_edge=TopoDS::Edge(edge.Current());
            TopoDS_Face c_face=TopoDS::Face(face.Current());
            Handle_Geom2d_Curve c=BRep_Tool::CurveOnSurface(c_edge,c_face,s,e);
            if(c.IsNull()) {
                if(verbose&Cutting)
                    cout << "Adding missing PCurve\n";
                ShapeFix_Edge().FixAddPCurve(c_edge,c_face,false,1e-7);
            }
        }
    }

    /***************************************************************************
        We determine which edges/wires are going to cut a face. To do this
        we create a map of FaceCutters which is indexed by the face number
        in the faces map. The FaceCutters generate the correct cutting wires.
    ***************************************************************************/
    int retry;
do {
    if(verbose&Cutting)
        std::cout << "STARTED CUTTING\n";
    retry=0;
    edges.Clear(); TopExp::MapShapes(result,TopAbs_EDGE,edges);
    faces.Clear(); TopExp::MapShapes(result,TopAbs_FACE,faces);
    cutmap_t cutters=SelectCuttingEdges(edges,faces);

    /***************************************************************************
        Apply all face splits stored in the map.
    ***************************************************************************/
    int cut_count=0;
    LocOpe_SplitShape splitter(result);
    for(cutmap_t::iterator f=cutters.begin(); f!=cutters.end(); f++) {
        TopoDS_Face const &face=TopoDS::Face(faces(f->first));
        FaceCutters &cutter=f->second;
        cut_count+=cutter.size();
        if(verbose&Cutting) {
            cout << "Cutting face " << f->first << " *************************\n";
            BRepTools::Dump(face,cout);
        }
        cutter.Build(face,result,verbose);
        for(FaceCutters::iterator p=cutter.begin(); p!=cutter.end(); p++) {
            TopTools_IndexedMapOfShape edges;
            TopExp::MapShapes(*p,TopAbs_EDGE,edges);
            if(edges.Extent()<3 && BRep_Tool::IsClosed(*p)) {
                // FIXME This doesn't work.
                cout << "IGNORED Closed wire with less than three edges\n";
                continue;
            }
            //BRepTools::Dump(*p,cout);
            try {
                splitter.Add(*p,face);
            }
            catch(Standard_ConstructionError c) {
                cout << "splitting the face failed\n";
                retry=1;
            }
        }
    }
    if(verbose&Cutting)
        cout << cut_count << " cuts in " << cutters.size() << " faces\n";

    // Create the final shape with the cutted faces.
    TopoDS_Compound cutted;
    BB.MakeCompound(cutted);
    int count=0;
    for(TopTools_ListIteratorOfListOfShape p(splitter.DescendantShapes(result));
        p.More();
        p.Next()
    ) {
        if(++count==1) {
            if(verbose&Cutting) {
                cout << "--------- " << count << " ---------------------------\n";
                BRepTools::Dump(p.Value(),cout);
            }
            BB.Add(cutted,p.Value());
        }
    }
    MergeFaces(cutted);
    result=cutted;
} while(0 && retry);
    target=result;
}
Пример #15
0
inline OCC_Connect::cutmap_t OCC_Connect::SelectCuttingEdges(
    TopTools_IndexedMapOfShape &edges,
    TopTools_IndexedMapOfShape &faces)
{
    cutmap_t cutters;
    for(int face=1;face<=faces.Extent();face++) {
        for(int edge=1;edge<=edges.Extent();edge++) {
            TopoDS_Edge c_edge=TopoDS::Edge(edges(edge));
            TopoDS_Face c_face=TopoDS::Face(faces(face));

            if(BRep_Tool::Degenerated(c_edge)) {
                if(verbose&CuttingReject)
                    cout << "Rejected(" << __LINE__ << ") edge " << edge
                        << " in face " << face << endl;
                continue;
            }

            TopTools_IndexedMapOfShape already_there;
            TopExp::MapShapes(c_face,TopAbs_EDGE,already_there);
            if(already_there.Contains(c_edge)) {
                if(verbose&CuttingReject)
                    cout << "Rejected(" << __LINE__ << ") edge " << edge
                        << " in face " << face << endl;
                continue;
            }

            BRepExtrema_DistShapeShape dist(c_edge,c_face);
            double tol=BRep_Tool::Tolerance(c_face);
            if(dist.Value()>tol) {
                if(verbose&CuttingReject)
                    cout << "Rejected(" << __LINE__ << ") edge " << edge
                        << " in face " << face << endl;
                continue;
            }

            Standard_Real s, e;
            Handle(Geom_Curve) c3d=BRep_Tool::Curve(c_edge,s,e);
            if(c3d.IsNull()) {
                if(verbose&CuttingReject)
                    cout << "Rejected(" << __LINE__ << ") edge " << edge
                        << " in face " << face << endl;
                continue;
            }

            // FIXME, checking only the middle may be a bit optimistic.
            TopoDS_Vertex vm=BRepBuilderAPI_MakeVertex(c3d->Value((s+e)/2));
            BRepExtrema_DistShapeShape dist_mf(vm,c_face);
            if(dist_mf.Value()>tol) {
                if(verbose&CuttingReject)
                    cout << "Rejected(" << __LINE__ << ") edge " << edge
                        << " in face " << face << endl;
                continue;
            }

            if(verbose&Cutting)
                cout << "Accepted edge " << edge << " in face " << face << endl;

            // Add missing PCurve if necessary
            Handle_Geom2d_Curve c=BRep_Tool::CurveOnSurface(c_edge,c_face,s,e);
            if(c.IsNull()) {
                if(verbose&Cutting)
                    cout << "Adding missing PCurve\n";
                ShapeFix_Edge().FixAddPCurve(c_edge,c_face,false,1e-7);
            }
            cutters[face].Add(c_edge);
        }
    }
    return cutters;
}
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);
  
}