Пример #1
0
// Make a TopoDS_Wire from a list of TopoDS_Edges
TopoDS_Wire edgesToWire(std::vector<TopoDS_Edge> Edges) {
    TopoDS_Wire occwire;
    std::vector<TopoDS_Edge>::iterator iEdge;
    BRepBuilderAPI_MakeWire mkWire;
    for (iEdge = Edges.begin(); iEdge != Edges.end(); ++iEdge){
        mkWire.Add(*iEdge);
        if (!mkWire.IsDone()) {
            Base::Console().Message("FT2FC Trace edgesToWire failed to add wire\n");
        }
    }
    occwire = mkWire.Wire();
    BRepLib::BuildCurves3d(occwire);
    return(occwire);
}
Пример #2
0
// Returns the wing profile lower and upper wire fused
TopoDS_Wire CCPACSWingProfile::GetSplitWire()
{
    Update();
    // rebuild closed wire
    BRepBuilderAPI_MakeWire closedWireBuilder;
    closedWireBuilder.Add(profileAlgo->GetLowerWire());
    closedWireBuilder.Add(profileAlgo->GetUpperWire());
    if (!profileAlgo->GetTrailingEdge().IsNull()) {
        closedWireBuilder.Add(profileAlgo->GetTrailingEdge());
    }
    closedWireBuilder.Build();
    
    if (!closedWireBuilder.IsDone()) {
        throw CTiglError("Error creating closed wing profile");
    }
        
    return closedWireBuilder.Wire();
}
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;
	}
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IFillet1d aCI (aFunction);

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShape = aRefShape->GetValue();
  if (aShape.IsNull())
    return 0;
  if (aShape.ShapeType() != TopAbs_WIRE)
    Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given");

  TopoDS_Wire aWire = TopoDS::Wire(aShape);

  double rad = aCI.GetR();

  if ( rad < Precision::Confusion())
    return 0;

  // collect vertices for make fillet
  TopTools_ListOfShape aVertexList;
  TopTools_MapOfShape mapShape;
  int aLen = aCI.GetLength();
  if ( aLen > 0 ) {
    for (int ind = 1; ind <= aLen; ind++) {
      TopoDS_Shape aShapeVertex;
      if (GEOMImpl_ILocalOperations::GetSubShape
          (aWire, aCI.GetVertex(ind), aShapeVertex))
        if (mapShape.Add(aShapeVertex))
          aVertexList.Append( aShapeVertex );
    }
  } else { // get all vertices from wire
    TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
    for ( ; anExp.More(); anExp.Next() ) {
      if (mapShape.Add(anExp.Current()))
        aVertexList.Append( anExp.Current() );
    }
  }
  if (aVertexList.IsEmpty())
    Standard_ConstructionError::Raise("Invalid input no vertices to make fillet");

  //INFO: this algorithm implemented in assumption that user can select both
  //  vertices of some edges to make fillet. In this case we should remember
  //  already modified initial edges to take care in next fillet step
  TopTools_DataMapOfShapeShape anEdgeToEdgeMap;

  //iterates on vertices, and make fillet on each couple of edges
  //collect result fillet edges in list
  TopTools_ListOfShape aListOfNewEdge;
  // remember relation between initial and modified map
  TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
  TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
  TopTools_ListIteratorOfListOfShape anIt( aVertexList );
  for ( ; anIt.More(); anIt.Next() ) {
    TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
    if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
      continue;
    const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV );
    if ( aVertexEdges.Extent() != 2 )
      continue; // no input data to make fillet
    TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() );
    TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() );
    // check if initial edges already modified in previous fillet operation
    if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 ));
    if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 ));
    if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) )
      continue; //no input data to make fillet

    // create plane on 2 edges
    gp_Pln aPlane;
    if ( !takePlane(anEdge1, anEdge2, aV, aPlane) )
      continue; // seems edges does not belong to same plane or parallel (fillet can not be build)

    GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane);
    if ( !aFilletAlgo.Perform(rad) )
      continue; // can not create fillet with given radius

    // take fillet result in given vertex
    TopoDS_Edge aModifE1, aModifE2;
    TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2);
    if (aNewE.IsNull())
      continue; // no result found

    // add  new created edges and take modified edges
    aListOfNewEdge.Append( aNewE );

    // check if face edges modified,
    // if yes, than map to original edges (from vertex-edges list), because edges can be modified before
    if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 );
    if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 );
  }

  if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) {
    StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
    return 0;
  }

  // create new wire instead of original
  for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
    TopoDS_Shape anEdge = anExp.Current();
    if ( !anEdgeToEdgeMap.IsBound( anEdge ) )
      aListOfNewEdge.Append( anEdge );
    else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull())
      aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) );
  }

  GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge );

  BRepBuilderAPI_MakeWire aWireTool;
  aWireTool.Add( aListOfNewEdge );
  aWireTool.Build();
  if (!aWireTool.IsDone())
    return 0;

  aWire = aWireTool.Wire();
  aFunction->SetValue(aWire);
  log.SetTouched(Label());

  return 1;
}
Пример #5
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;
}
Пример #6
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;
	}
}
Пример #7
0
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

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

  TopoDS_Shape aShape;

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShapeBase = aRefShape->GetValue();



  if (aType == CHAMFER_SHAPE_EDGES_2D)
  {
	BRepFilletAPI_MakeFillet2d fill;
	TopoDS_Face aFace;

	Standard_Boolean aWireFlag = Standard_False;
	
	if (aShapeBase.ShapeType() == TopAbs_FACE)
		aFace = TopoDS::Face(aShapeBase);
	else if (aShapeBase.ShapeType() == TopAbs_WIRE)
	{
		TopoDS_Wire aWire = TopoDS::Wire(aShapeBase);
		BRepBuilderAPI_MakeFace aMF(aWire);
		aMF.Build();
		if (!aMF.IsDone()) {
			StdFail_NotDone::Raise("Cannot build initial face from given wire");
		}
		aFace = aMF.Face();
		aWireFlag = Standard_True;
	}
	else
		StdFail_NotDone::Raise("Base shape is neither a face or a wire !");

	fill.Init(aFace);

	double aD1_2D = aCI.GetD1();
	double aD2_2D = aCI.GetD2();

	TopoDS_Shape aShapeFace1, aShapeFace2;

	if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge1(), aShapeFace1) &&
		GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge2(), aShapeFace2))
	{
		fill.AddChamfer(TopoDS::Edge(aShapeFace1), TopoDS::Edge(aShapeFace2), aD1_2D, aD2_2D);
	}
	else
		StdFail_NotDone::Raise("Cannot get 2d egde from sub-shape index!");

	fill.Build();
	if (!fill.IsDone()) {
		StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
	}
	if (aWireFlag)
	{
		BRepBuilderAPI_MakeWire MW;
		TopExp_Explorer exp (fill.Shape(), TopAbs_EDGE);
		for (; exp.More(); exp.Next())
			MW.Add(TopoDS::Edge(exp.Current()));
		MW.Build();
		if (!MW.IsDone())
			StdFail_NotDone::Raise("Resulting wire cannot be built");
			
		aShape = MW.Shape();
	}
	else
		aShape = fill.Shape();
  }
  else
  {
	  // Check the shape type. It have to be shell
	  // or solid, or compsolid, or compound of these shapes.
	  if (!isGoodForChamfer(aShapeBase)) {
		StdFail_NotDone::Raise
		  ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes");
	  }

	  BRepFilletAPI_MakeChamfer fill (aShapeBase);

	  if (aType == CHAMFER_SHAPE_ALL) {
		// symmetric chamfer on all edges
		double aD = aCI.GetD();
		TopTools_IndexedDataMapOfShapeListOfShape M;
		GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
		for (int i = 1; i <= M.Extent(); i++) {
		  TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
		  TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
		  if (!BRepTools::IsReallyClosed(E, F) &&
			  !BRep_Tool::Degenerated(E) &&
			  M.FindFromIndex(i).Extent() == 2)
			fill.Add(aD, E, F);
		}
	  }else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) {
		// chamfer on edges, common to two faces, with D1 on the first face

		TopoDS_Shape aFace1, aFace2;
		if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) &&
			GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2))
		  {
		TopoDS_Face F = TopoDS::Face(aFace1);

		// fill map of edges of the second face
		TopTools_MapOfShape aMap;
		TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE);
		for (; Exp2.More(); Exp2.Next()) {
		  aMap.Add(Exp2.Current());
		}
	
		// find edges of the first face, common with the second face
		TopExp_Explorer Exp (aFace1, TopAbs_EDGE);
		for (; Exp.More(); Exp.Next()) {
		  if (aMap.Contains(Exp.Current())) {
			TopoDS_Edge E = TopoDS::Edge(Exp.Current());
			if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
			  {
			if ( aType == CHAMFER_SHAPE_EDGE )
			  {
				double aD1 = aCI.GetD1();
				double aD2 = aCI.GetD2();
				fill.Add(aD1, aD2, E, F);
			  }
			else
			  {
				double aD = aCI.GetD();
				double anAngle = aCI.GetAngle();
				if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) )
				  fill.AddDA(aD, anAngle, E, F);
			  }
			  }
		  }
		}
		  }
	  }
	  else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) {
		// chamfer on all edges of the selected faces, with D1 on the selected face
		// (on first selected face, if the edge belongs to two selected faces)

		int aLen = aCI.GetLength();
		int ind = 1;
		TopTools_MapOfShape aMap;
		TopTools_IndexedDataMapOfShapeListOfShape M;
		GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
		for (; ind <= aLen; ind++)
		{
		  TopoDS_Shape aShapeFace;
		  if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace))
		{
		  TopoDS_Face F = TopoDS::Face(aShapeFace);
		  TopExp_Explorer Exp (F, TopAbs_EDGE);
		  for (; Exp.More(); Exp.Next()) {
			if (!aMap.Contains(Exp.Current()))
			  {
			TopoDS_Edge E = TopoDS::Edge(Exp.Current());
			if (!BRepTools::IsReallyClosed(E, F) &&
				!BRep_Tool::Degenerated(E) &&
				M.FindFromKey(E).Extent() == 2)
			  if (aType == CHAMFER_SHAPE_FACES)
				{
				  double aD1 = aCI.GetD1();
				  double aD2 = aCI.GetD2();
				  fill.Add(aD1, aD2, E, F);
				}
			  else
				{
				  double aD = aCI.GetD();
				  double anAngle = aCI.GetAngle();
				  if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) )
				fill.AddDA(aD, anAngle, E, F);
				}
			  }
		  }
		}
		}
	  }
	else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD)
	  {
		// chamfer on selected edges with lenght param D1 & D2.

		int aLen = aCI.GetLength();
		int ind = 1;
		TopTools_MapOfShape aMap;
		TopTools_IndexedDataMapOfShapeListOfShape M;
		GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
		for (; ind <= aLen; ind++)
		{
		  TopoDS_Shape aShapeEdge;
		  if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge))
		{
		  TopoDS_Edge E = TopoDS::Edge(aShapeEdge);
		  const TopTools_ListOfShape& aFacesList = M.FindFromKey(E);
		  TopoDS_Face F = TopoDS::Face( aFacesList.First() );
		  if (aType == CHAMFER_SHAPE_EDGES)
			{
			  double aD1 = aCI.GetD1();
			  double aD2 = aCI.GetD2();
			  fill.Add(aD1, aD2, E, F);
			}
		  else
			{
			  double aD = aCI.GetD();
			  double anAngle = aCI.GetAngle();
			  if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) )
			fill.AddDA(aD, anAngle, E, F);
			}
		}
		}
	  }
	  else {
	  }

	  fill.Build();
	  if (!fill.IsDone()) {
		StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
	  }
	  aShape = fill.Shape();
  }

  if (aShape.IsNull()) return 0;

  // Check shape validity
  BRepCheck_Analyzer ana (aShape, false);
  if (!ana.IsValid()) {
  	// 08.07.2008 added by skl during fixing bug 19761 from Mantis
	ShapeFix_ShapeTolerance aSFT;
	aSFT.LimitTolerance(aShape, Precision::Confusion(),
						Precision::Confusion(), TopAbs_SHAPE);
	Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
	aSfs->Perform();
	aShape = aSfs->Shape();

    // fix SameParameter flag
    BRepLib::SameParameter(aShape, 1.E-5, Standard_True);

	ana.Init(aShape);
	if (!ana.IsValid()) {
	  Standard_CString anErrStr("Chamfer algorithm has produced an invalid shape result");
	  #ifdef THROW_ON_INVALID_SH
		Standard_ConstructionError::Raise(anErrStr);
	  #else
		MESSAGE(anErrStr);
		//further processing can be performed here
		//...
		//in case of failure of automatic treatment
		//mark the corresponding GEOM_Object as problematic
		TDF_Label aLabel = aFunction->GetOwnerEntry();
		if (!aLabel.IsRoot()) {
		  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
		  if (!aMainObj.IsNull())
			aMainObj->SetDirty(Standard_True);
		}
	  #endif
	}
  }

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}