void TestMkFillet(){
    TopoDS_Shape Box = BRepPrimAPI_MakeBox(10., 10., 10.);
    BRepFilletAPI_MakeFillet mkFillet(Box);

    TopTools_IndexedMapOfShape edges;
    TopExp::MapShapes(Box, TopAbs_EDGE, edges);
    TopoDS_Edge edge = TopoDS::Edge(edges.FindKey(3));

    mkFillet.Add(1., 1., edge);
    mkFillet.Build();

    TopoDS_Shape result = mkFillet.Shape();


    TopTools_IndexedMapOfShape faces;
    TopExp::MapShapes(Box, TopAbs_FACE, faces);
    TopoDS_Face face = TopoDS::Face(faces.FindKey(3));

    TopTools_ListOfShape modified = mkFillet.Modified(face);
    TopTools_ListIteratorOfListOfShape modIt;
    for (int i=1; modIt.More(); modIt.Next(), i++){
        TopoDS_Face curFace = TopoDS::Face(modIt.Value());
        TopoNamingHelper::WriteShape(curFace, "00_02_ModifiedFace", i);
    }

    TopoNamingHelper::WriteShape(result, "00_00_FilletResult");
    TopoNamingHelper::WriteShape(face, "00_01_BaseFace_3");
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOM_SubShapeDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOM_ISubShape aCI (aFunction);

  TDF_Label aLabel = aCI.GetMainShape()->GetOwnerEntry();
  if (aLabel.IsRoot()) return 0;
  Handle(GEOM_Object) anObj = GEOM_Object::GetObject(aLabel);
  if (anObj.IsNull()) return 0;
  TopoDS_Shape aMainShape = anObj->GetValue();
  if (aMainShape.IsNull()) return 0;

  Handle(TColStd_HArray1OfInteger) anIndices = aCI.GetIndices();
  if (anIndices.IsNull() || anIndices->Length() <= 0) return 0;

  BRep_Builder B;
  TopoDS_Compound aCompound;
  TopoDS_Shape aShape;

  if (anIndices->Length() == 1 && anIndices->Value(1) == -1) { //The empty sub-shape
    B.MakeCompound(aCompound);
    aShape = aCompound;
  }
  else {
    TopTools_IndexedMapOfShape aMapOfShapes;
    TopExp::MapShapes(aMainShape, aMapOfShapes);

    if (anIndices->Length() > 1) {
      B.MakeCompound(aCompound);

      for (int i = anIndices->Lower(); i <= anIndices->Upper(); i++) {
        if (aMapOfShapes.Extent() < anIndices->Value(i))
          Standard_NullObject::Raise("GEOM_SubShapeDriver::Execute: Index is out of range");
        TopoDS_Shape aSubShape = aMapOfShapes.FindKey(anIndices->Value(i));
        if (aSubShape.IsNull()) continue;
        B.Add(aCompound,aSubShape);
      }

      aShape = aCompound;
    }
    else {
      int i = anIndices->Lower();
      if (aMapOfShapes.Extent() < anIndices->Value(i))
        Standard_NullObject::Raise("GEOM_SubShapeDriver::Execute: Index is out of range");
      aShape = aMapOfShapes.FindKey(anIndices->Value(i));
    }
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
Esempio n. 3
0
void FaceMakerExtrusion::Build()
{
    this->NotDone();
    this->myGenerated.Clear();
    this->myShapesToReturn.clear();
    this->myShape = TopoDS_Shape();
    TopoDS_Shape inputShape;
    if (mySourceShapes.empty())
        throw Base::Exception("No input shapes!");
    if (mySourceShapes.size() == 1){
        inputShape = mySourceShapes[0];
    } else {
        TopoDS_Builder builder;
        TopoDS_Compound cmp;
        builder.MakeCompound(cmp);
        for (const TopoDS_Shape& sh: mySourceShapes){
            builder.Add(cmp, sh);
        }
        inputShape = cmp;
    }

    std::vector<TopoDS_Wire> wires;
    TopTools_IndexedMapOfShape mapOfWires;
    TopExp::MapShapes(inputShape, TopAbs_WIRE, mapOfWires);

    // if there are no wires then check also for edges
    if (mapOfWires.IsEmpty()) {
        TopTools_IndexedMapOfShape mapOfEdges;
        TopExp::MapShapes(inputShape, TopAbs_EDGE, mapOfEdges);
        for (int i=1; i<=mapOfEdges.Extent(); i++) {
            BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(mapOfEdges.FindKey(i)));
            wires.push_back(mkWire.Wire());
        }
    }
    else {
        wires.reserve(mapOfWires.Extent());
        for (int i=1; i<=mapOfWires.Extent(); i++) {
            wires.push_back(TopoDS::Wire(mapOfWires.FindKey(i)));
        }
    }

    if (!wires.empty()) {
        //try {
            TopoDS_Shape res = FaceMakerCheese::makeFace(wires);
            if (!res.IsNull())
                this->myShape = res;
        //}
        //catch (...) {

        //}
    }

    this->Done();

}
//=======================================================================
//function :  AddPointOnEdge
//purpose  :
//=======================================================================
Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
                                                         const TopoDS_Shape& theOriginalShape,
                                                         TopoDS_Shape& theOutShape) const
{
  Standard_Boolean isByParameter = theHI->GetIsByParameter();
  Standard_Integer anIndex = theHI->GetIndex();
  Standard_Real aValue = theHI->GetDevideEdgeValue();

  ShHealOper_EdgeDivide aHealer (theOriginalShape);

  Standard_Boolean aResult = Standard_False;
  if (anIndex == -1) { // apply algorythm for the whole shape which is EDGE
    if (theOriginalShape.ShapeType() == TopAbs_EDGE)
      aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
  } else {
    TopTools_IndexedMapOfShape aShapes;
    TopExp::MapShapes(theOriginalShape, aShapes);
    TopoDS_Shape aEdgeShape = aShapes.FindKey(anIndex);
    if (aEdgeShape.ShapeType() == TopAbs_EDGE)
      aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
  }

  if (aResult)
    theOutShape = aHealer.GetResultShape();
  else
    raiseNotDoneExeption( aHealer.GetErrorStatus() );

  return aResult;
}
//=======================================================================
//function :  RemoveHoles
//purpose  :
//=======================================================================
Standard_Boolean GEOMImpl_HealingDriver::RemoveHoles (GEOMImpl_IHealing* theHI,
                                                      const TopoDS_Shape& theOriginalShape,
                                                      TopoDS_Shape& theOutShape) const
{
  Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();

  ShHealOper_FillHoles aHealer (theOriginalShape);

  Standard_Boolean aResult = Standard_False;
  if (aWires.IsNull()) { // remove all faces
    aResult = aHealer.Fill();
  } else {
    TopTools_SequenceOfShape aShapesWires;
    TopTools_IndexedMapOfShape aShapes;
    TopExp::MapShapes(theOriginalShape, aShapes);
    for (int i = 1; i <= aWires->Length(); i++) {
      int indexOfWire = aWires->Value(i);
      TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
      aShapesWires.Append(aWire);
    }

    aResult = aHealer.Fill(aShapesWires);
  }

  if (aResult)
    theOutShape = aHealer.GetResultShape();
  else
    raiseNotDoneExeption( aHealer.GetErrorStatus() );

  return aResult;
}
//=======================================================================
//function :  CloseContour
//purpose  :
//=======================================================================
Standard_Boolean GEOMImpl_HealingDriver::CloseContour (GEOMImpl_IHealing* theHI,
                                                       const TopoDS_Shape& theOriginalShape,
                                                       TopoDS_Shape& theOutShape) const
{
  Standard_Boolean isByVertex = theHI->GetIsCommonVertex();
  Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();

  ShHealOper_CloseContour aHealer (theOriginalShape);

  Standard_Boolean aResult = Standard_False;
  if ( aWires.IsNull() ) {
    if ( theOriginalShape.ShapeType() == TopAbs_WIRE )
      aResult = aHealer.Perform(TopoDS::Wire(theOriginalShape), isByVertex, !isByVertex);
  }
  else {
    TopTools_SequenceOfShape aShapesWires;
    TopTools_IndexedMapOfShape aShapes;
    TopExp::MapShapes(theOriginalShape, aShapes);
    for (int i = 1; i <= aWires->Length(); i++) {
      int indexOfWire = aWires->Value(i);
      TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
      aShapesWires.Append(aWire);
    }

    aResult = aHealer.Perform( aShapesWires, isByVertex, !isByVertex );
  }

  if (aResult)
    theOutShape = aHealer.GetResultShape();
  else
    raiseNotDoneExeption( aHealer.GetErrorStatus() );

  return aResult;
}
Esempio n. 7
0
App::DocumentObjectExecReturn *Fillet::execute(void)
{
    App::DocumentObject* link = Base.getValue();
    if (!link)
        return new App::DocumentObjectExecReturn("No object linked");
    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Linked object is not a Part object");
    Part::Feature *base = static_cast<Part::Feature*>(Base.getValue());

    try {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
        Base::SignalException se;
#endif
        BRepFilletAPI_MakeFillet mkFillet(base->Shape.getValue());
        TopTools_IndexedMapOfShape mapOfShape;
        TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, mapOfShape);

        std::vector<FilletElement> values = Edges.getValues();
        for (std::vector<FilletElement>::iterator it = values.begin(); it != values.end(); ++it) {
            int id = it->edgeid;
            double radius1 = it->radius1;
            double radius2 = it->radius2;
            const TopoDS_Edge& edge = TopoDS::Edge(mapOfShape.FindKey(id));
            mkFillet.Add(radius1, radius2, edge);
        }

        TopoDS_Shape shape = mkFillet.Shape();
        if (shape.IsNull())
            return new App::DocumentObjectExecReturn("Resulting shape is null");
        ShapeHistory history = buildHistory(mkFillet, TopAbs_FACE, shape, base->Shape.getValue());
        this->Shape.setValue(shape);

        // make sure the 'PropertyShapeHistory' is not safed in undo/redo (#0001889)
        PropertyShapeHistory prop;
        prop.setValue(history);
        prop.setContainer(this);
        prop.touch();

        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
    catch (...) {
        return new App::DocumentObjectExecReturn("A fatal error occurred when making fillets");
    }
}
void collectConicEdges(const TopoDS_Shell &shell, TopTools_IndexedMapOfShape &map)
{
  TopTools_IndexedMapOfShape edges;
  TopExp::MapShapes(shell, TopAbs_EDGE, edges);
  
  for (int index = 1; index <= edges.Extent(); ++index)
  {
    const TopoDS_Edge &currentEdge = TopoDS::Edge(edges.FindKey(index));
    if (currentEdge.IsNull())
      continue;
    TopLoc_Location location;
    Standard_Real first, last;
    const Handle_Geom_Curve &curve = BRep_Tool::Curve(currentEdge, location, first, last);
    if (curve.IsNull())
      continue;
    if (curve->IsKind(STANDARD_TYPE(Geom_Conic)))
      map.Add(currentEdge);
  }
}
Standard_Boolean GEOMImpl_HealingDriver::SuppressFaces (GEOMImpl_IHealing* theHI,
                                                        const TopoDS_Shape& theOriginalShape,
                                                        TopoDS_Shape& theOutShape) const
{
  Handle(TColStd_HArray1OfInteger) aFaces = theHI->GetFaces();

  Standard_Boolean aResult = Standard_False;

  if (aFaces.IsNull()) {
    ShHealOper_RemoveFace aHealer (theOriginalShape);
    aResult = aHealer.Perform();

    if (aResult)
      theOutShape = aHealer.GetResultShape();
    else
      raiseNotDoneExeption(aHealer.GetErrorStatus());
  }
  else {
    TopTools_SequenceOfShape aShapesFaces;
    TopTools_IndexedMapOfShape aShapes;
    TopExp::MapShapes(theOriginalShape, aShapes);
    for (int i = 1; i <= aFaces->Length(); i++) {
      int indexOfFace = aFaces->Value(i);
      TopoDS_Shape aFace = aShapes.FindKey(indexOfFace);
      aShapesFaces.Append(aFace);
    }
    SuppressFacesRec(aShapesFaces, theOriginalShape, theOutShape);
    if ((theOriginalShape.ShapeType() == TopAbs_COMPOUND ||
         theOriginalShape.ShapeType() == TopAbs_COMPSOLID)) {
      TopoDS_Shape aSh = theOutShape;
      theOutShape = GEOMImpl_GlueDriver::GlueFaces(aSh, Precision::Confusion(), Standard_True);
    }
  }

  return Standard_True;
}
Esempio n. 10
0
bool ProfileBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Face &face)
{
#if 1
    BRepBuilderAPI_MakeEdge mkEdge(line);
    TopoDS_Wire wire = ShapeAnalysis::OuterWire(face);
    BRepExtrema_DistShapeShape distss(wire, mkEdge.Shape(), Precision::Confusion());
    if (distss.IsDone()) {
        if (distss.Value() > Precision::Confusion())
            return false;
        // build up map vertex->edge
        TopTools_IndexedDataMapOfShapeListOfShape vertex2Edge;
        TopExp::MapShapesAndAncestors(wire, TopAbs_VERTEX, TopAbs_EDGE, vertex2Edge);

        for (Standard_Integer i=1; i<= distss.NbSolution(); i++) {
            if (distss.PointOnShape1(i).Distance(distss.PointOnShape2(i)) > Precision::Confusion())
                continue;
            BRepExtrema_SupportType type = distss.SupportTypeShape1(i);
            if (type == BRepExtrema_IsOnEdge) {
                TopoDS_Edge edge = TopoDS::Edge(distss.SupportOnShape1(i));
                BRepAdaptor_Curve adapt(edge);
                // create a plane (pnt,dir) that goes through the intersection point and is built of
                // the vectors of the sketch normal and the rotation axis
                const gp_Dir& normal = BRepAdaptor_Surface(face).Plane().Axis().Direction();
                gp_Dir dir = line.Direction().Crossed(normal);
                gp_Pnt pnt = distss.PointOnShape1(i);

                Standard_Real t;
                distss.ParOnEdgeS1(i, t);
                gp_Pnt p_eps1 = adapt.Value(std::max<double>(adapt.FirstParameter(), t-10*Precision::Confusion()));
                gp_Pnt p_eps2 = adapt.Value(std::min<double>(adapt.LastParameter(), t+10*Precision::Confusion()));

                // now check if we get a change in the sign of the distances
                Standard_Real dist_p_eps1_pnt = gp_Vec(p_eps1, pnt).Dot(gp_Vec(dir));
                Standard_Real dist_p_eps2_pnt = gp_Vec(p_eps2, pnt).Dot(gp_Vec(dir));
                // distance to the plane must be noticeable
                if (fabs(dist_p_eps1_pnt) > 5*Precision::Confusion() &&
                    fabs(dist_p_eps2_pnt) > 5*Precision::Confusion()) {
                    if (dist_p_eps1_pnt * dist_p_eps2_pnt < 0)
                        return true;
                }
            }
            else if (type == BRepExtrema_IsVertex) {
                // for a vertex check the two adjacent edges if there is a change of sign
                TopoDS_Vertex vertex = TopoDS::Vertex(distss.SupportOnShape1(i));
                const TopTools_ListOfShape& edges = vertex2Edge.FindFromKey(vertex);
                if (edges.Extent() == 2) {
                    // create a plane (pnt,dir) that goes through the intersection point and is built of
                    // the vectors of the sketch normal and the rotation axis
                    BRepAdaptor_Surface adapt(face);
                    const gp_Dir& normal = adapt.Plane().Axis().Direction();
                    gp_Dir dir = line.Direction().Crossed(normal);
                    gp_Pnt pnt = distss.PointOnShape1(i);

                    // from the first edge get a point next to the intersection point
                    const TopoDS_Edge& edge1 = TopoDS::Edge(edges.First());
                    BRepAdaptor_Curve adapt1(edge1);
                    Standard_Real dist1 = adapt1.Value(adapt1.FirstParameter()).SquareDistance(pnt);
                    Standard_Real dist2 = adapt1.Value(adapt1.LastParameter()).SquareDistance(pnt);
                    gp_Pnt p_eps1;
                    if (dist1 < dist2)
                        p_eps1 = adapt1.Value(adapt1.FirstParameter() + 2*Precision::Confusion());
                    else
                        p_eps1 = adapt1.Value(adapt1.LastParameter() - 2*Precision::Confusion());

                    // from the second edge get a point next to the intersection point
                    const TopoDS_Edge& edge2 = TopoDS::Edge(edges.Last());
                    BRepAdaptor_Curve adapt2(edge2);
                    Standard_Real dist3 = adapt2.Value(adapt2.FirstParameter()).SquareDistance(pnt);
                    Standard_Real dist4 = adapt2.Value(adapt2.LastParameter()).SquareDistance(pnt);
                    gp_Pnt p_eps2;
                    if (dist3 < dist4)
                        p_eps2 = adapt2.Value(adapt2.FirstParameter() + 2*Precision::Confusion());
                    else
                        p_eps2 = adapt2.Value(adapt2.LastParameter() - 2*Precision::Confusion());

                    // now check if we get a change in the sign of the distances
                    Standard_Real dist_p_eps1_pnt = gp_Vec(p_eps1, pnt).Dot(gp_Vec(dir));
                    Standard_Real dist_p_eps2_pnt = gp_Vec(p_eps2, pnt).Dot(gp_Vec(dir));
                    // distance to the plane must be noticeable
                    if (fabs(dist_p_eps1_pnt) > Precision::Confusion() &&
                        fabs(dist_p_eps2_pnt) > Precision::Confusion()) {
                        if (dist_p_eps1_pnt * dist_p_eps2_pnt < 0)
                            return true;
                    }
                }
            }
        }
    }

    return false;
#else
    // This is not as easy as it looks, because a distance of zero might be OK if
    // the axis touches the sketchshape in in a linear edge or a vertex
    // Note: This algorithm does not catch cases where the sketchshape touches the
    // axis in two or more points
    // Note: And it only works on closed outer wires
    TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(face);
    BRepBuilderAPI_MakeEdge mkEdge(line);
    if (!mkEdge.IsDone())
        throw Base::RuntimeError("Revolve: Unexpected OCE failure");
    BRepAdaptor_Curve axis(TopoDS::Edge(mkEdge.Shape()));

    TopExp_Explorer ex;
    int intersections = 0;
    std::vector<gp_Pnt> intersectionpoints;

    // Note: We need to look at every edge separately to catch coincident lines
    for (ex.Init(outerWire, TopAbs_EDGE); ex.More(); ex.Next()) {
        BRepAdaptor_Curve edge(TopoDS::Edge(ex.Current()));
        Extrema_ExtCC intersector(axis, edge);

        if (intersector.IsDone()) {
            for (int i = 1; i <= intersector.NbExt(); i++) {


#if OCC_VERSION_HEX >= 0x060500
                if (intersector.SquareDistance(i) < Precision::Confusion()) {
#else
                if (intersector.Value(i) < Precision::Confusion()) {
#endif
                    if (intersector.IsParallel()) {
                        // A line that is coincident with the axis produces three intersections
                        // 1 with the line itself and 2 with the adjacent edges
                        intersections -= 2;
                    } else {
                        Extrema_POnCurv p1, p2;
                        intersector.Points(i, p1, p2);
                        intersectionpoints.push_back(p1.Value());
                        intersections++;
                    }
                }
            }
        }
    }

    // Note: We might check this inside the loop but then we have to rely on TopExp_Explorer
    // returning the wire's edges in adjacent order (because of the coincident line checking)
    if (intersections > 1) {
        // Check that we don't touch the sketchface just in two identical vertices
        if ((intersectionpoints.size() == 2) &&
            (intersectionpoints[0].IsEqual(intersectionpoints[1], Precision::Confusion())))
            return false;
        else
            return true;
    }

    return false;
#endif
}

void ProfileBased::remapSupportShape(const TopoDS_Shape& newShape)
{
    TopTools_IndexedMapOfShape faceMap;
    TopExp::MapShapes(newShape, TopAbs_FACE, faceMap);

    // here we must reset the placement otherwise the geometric matching doesn't work
    Part::TopoShape shape = this->Shape.getValue();
    TopoDS_Shape sh = shape.getShape();
    sh.Location(TopLoc_Location());
    shape.setShape(sh);

    std::vector<App::DocumentObject*> refs = this->getInList();
    for (std::vector<App::DocumentObject*>::iterator it = refs.begin(); it != refs.end(); ++it) {
        std::vector<App::Property*> props;
        (*it)->getPropertyList(props);
        for (std::vector<App::Property*>::iterator jt = props.begin(); jt != props.end(); ++jt) {
            if (!(*jt)->isDerivedFrom(App::PropertyLinkSub::getClassTypeId()))
                continue;
            App::PropertyLinkSub* link = static_cast<App::PropertyLinkSub*>(*jt);
            if (link->getValue() != this)
                continue;
            std::vector<std::string> subValues = link->getSubValues();
            std::vector<std::string> newSubValues;

            for (std::vector<std::string>::iterator it = subValues.begin(); it != subValues.end(); ++it) {
                std::string shapetype;
                if (it->size() > 4 && it->substr(0,4) == "Face") {
                    shapetype = "Face";
                }
                else if (it->size() > 4 && it->substr(0,4) == "Edge") {
                    shapetype = "Edge";
                }
                else if (it->size() > 6 && it->substr(0,6) == "Vertex") {
                    shapetype = "Vertex";
                }
                else {
                    newSubValues.push_back(*it);
                    continue;
                }

                bool success = false;
                TopoDS_Shape element;
                try {
                    element = shape.getSubShape(it->c_str());
                }
                catch (Standard_Failure&) {
                    // This shape doesn't even exist, so no chance to do some tests
                    newSubValues.push_back(*it);
                    continue;
                }
                try {
                    // as very first test check if old face and new face are parallel planes
                    TopoDS_Shape newElement = Part::TopoShape(newShape).getSubShape(it->c_str());
                    if (isParallelPlane(element, newElement)) {
                        newSubValues.push_back(*it);
                        success = true;
                    }
                }
                catch (Standard_Failure&) {
                }
                // try an exact matching
                if (!success) {
                    for (int i=1; i<faceMap.Extent(); i++) {
                        if (isQuasiEqual(element, faceMap.FindKey(i))) {
                            std::stringstream str;
                            str << shapetype << i;
                            newSubValues.push_back(str.str());
                            success = true;
                            break;
                        }
                    }
                }
                // if an exact matching fails then try to compare only the geometries
                if (!success) {
                    for (int i=1; i<faceMap.Extent(); i++) {
                        if (isEqualGeometry(element, faceMap.FindKey(i))) {
                            std::stringstream str;
                            str << shapetype << i;
                            newSubValues.push_back(str.str());
                            success = true;
                            break;
                        }
                    }
                }

                // the new shape couldn't be found so keep the old sub-name
                if (!success)
                    newSubValues.push_back(*it);
            }

            link->setValue(this, newSubValues);
        }
    }
}
Esempio n. 11
0
TopoDS_Shape BlockFix_UnionEdges::Perform(const TopoDS_Shape& Shape,
                                          const Standard_Real Tol)
{
  myContext = new ShapeBuild_ReShape;
  myTolerance = Tol;
  TopoDS_Shape aResult = myContext->Apply(Shape);

  // processing each solid
  TopAbs_ShapeEnum aType = TopAbs_SOLID;
  TopExp_Explorer exps (Shape, aType);
  if (!exps.More()) {
    aType = TopAbs_SHELL;
    exps.Init(Shape, aType);
  }
  for (; exps.More(); exps.Next()) {
    //TopoDS_Solid aSolid = TopoDS::Solid(exps.Current());
    TopoDS_Shape aSolid = exps.Current();

    TopTools_IndexedMapOfShape ChangedFaces;

    // creating map of edge faces
    TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
    TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);

    Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
    TopoDS_Shape aRes = aSolid;
    aRes = aContext->Apply(aSolid);

    // processing each face
    TopExp_Explorer exp;
    for (exp.Init(aRes, TopAbs_FACE); exp.More(); exp.Next()) {
      TopoDS_Face aFace =
        TopoDS::Face(aContext->Apply(exp.Current().Oriented(TopAbs_FORWARD)));
      TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges;

      for (TopExp_Explorer expe(aFace,TopAbs_EDGE); expe.More(); expe.Next()) {
        TopoDS_Edge edge = TopoDS::Edge(expe.Current());
        if (!aMapEdgeFaces.Contains(edge)) continue;
        const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
        TopTools_ListIteratorOfListOfShape anIter(aList);
        for ( ; anIter.More(); anIter.Next()) {
          TopoDS_Face face = TopoDS::Face(anIter.Value());
          TopoDS_Face face1 = TopoDS::Face(aContext->Apply(anIter.Value()));
          if (face1.IsSame(aFace)) continue;
          if (aMapFacesEdges.Contains(face)) {
            aMapFacesEdges.ChangeFromKey(face).Append(edge);
          }
          else {
            TopTools_ListOfShape ListEdges;
            ListEdges.Append(edge);
            aMapFacesEdges.Add(face,ListEdges);
          }
        }
      }

      for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++) {
        const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
        TopTools_SequenceOfShape SeqEdges;
        TopTools_ListIteratorOfListOfShape anIter(ListEdges);
        for ( ; anIter.More(); anIter.Next()) {
          SeqEdges.Append(anIter.Value());
        }
        if (SeqEdges.Length()==1) continue;
        TopoDS_Edge E;
        if ( MergeEdges(SeqEdges,aFace,Tol,E) ) {
          // now we have only one edge - aChain.Value(1)
          // we have to replace old ListEdges with this new edge
          aContext->Replace(SeqEdges(1),E);
          for (Standard_Integer j=2; j<=SeqEdges.Length(); j++) {
            aContext->Remove(SeqEdges(j));
          }
          TopoDS_Face tmpF = TopoDS::Face(exp.Current());
          if ( !ChangedFaces.Contains(tmpF) )
            ChangedFaces.Add(tmpF);
          tmpF = TopoDS::Face(aMapFacesEdges.FindKey(i));
          if ( !ChangedFaces.Contains(tmpF) )
            ChangedFaces.Add(tmpF);
        }
      }

    } // end processing each face

    // fix changed faces and replace them in the local context
    for (Standard_Integer i=1; i<=ChangedFaces.Extent(); i++) {
      TopoDS_Face aFace = TopoDS::Face(aContext->Apply(ChangedFaces.FindKey(i)));
      Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace);
      sff->SetContext(myContext);
      sff->SetPrecision(myTolerance);
      sff->SetMinTolerance(myTolerance);
      sff->SetMaxTolerance(Max(1.,myTolerance*1000.));
      sff->Perform();
      aContext->Replace(aFace,sff->Face());
    }

    if (ChangedFaces.Extent() > 0) {
      // fix changed shell and replace it in the local context
      TopoDS_Shape aRes1 = aContext->Apply(aRes);
      TopExp_Explorer expsh;
      for (expsh.Init(aRes1, TopAbs_SHELL); expsh.More(); expsh.Next()) {
        TopoDS_Shell aShell = TopoDS::Shell(expsh.Current());
        Handle(ShapeFix_Shell) sfsh = new ShapeFix_Shell;
        sfsh->FixFaceOrientation(aShell);
        aContext->Replace(aShell,sfsh->Shell());
      }
      TopoDS_Shape aRes2 = aContext->Apply(aRes1);
      // put new solid into global context
      myContext->Replace(aSolid,aRes2);
    }

  } // end processing each solid

  aResult = myContext->Apply(Shape);
  return aResult;
}
  STEPIMPORT_EXPORT
  TopoDS_Shape ImportSTEP (const TCollection_AsciiString& theFileName,
                       const TCollection_AsciiString& /*theFormatName*/,
                       TCollection_AsciiString&       theError,
                       const TDF_Label&               theShapeLabel)
  {
    MESSAGE("Import STEP model from file " << theFileName.ToCString());
    // Set "C" numeric locale to save numbers correctly
    //Kernel_Utils::Localizer loc;
    TopoDS_Shape aResShape;
    //VRV: OCC 4.0 migration
    STEPControl_Reader aReader;
    //VSR: 16/09/09: Convert to METERS
    Interface_Static::SetCVal("xstep.cascade.unit","M");
    Interface_Static::SetIVal("read.step.ideas", 1);
    Interface_Static::SetIVal("read.step.nonmanifold", 1);
    //VRV: OCC 4.0 migration
    TopoDS_Compound compound;
    BRep_Builder B;
    B.MakeCompound(compound);
    try {
#if OCC_VERSION_LARGE > 0x06010000
      OCC_CATCH_SIGNALS;
#endif
      IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.ToCString());

      if (status == IFSelect_RetDone) {
        Standard_Boolean failsonly = Standard_False;
        aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
        /* Root transfers */
        Standard_Integer nbr = aReader.NbRootsForTransfer();
        aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);

        for (Standard_Integer n = 1; n <= nbr; n++) {
          Standard_Boolean ok = aReader.TransferRoot(n);
          /* Collecting resulting entities */
          Standard_Integer nbs = aReader.NbShapes();
          if (!ok || nbs == 0)
          {
            // THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM);
            continue; // skip empty root
          }
          /* For a single entity */
          else if (nbr == 1 && nbs == 1) {
            aResShape = aReader.Shape(1);
            // ATTENTION: this is a workaround for mantis issue 0020442 remark 0010776
            // It should be removed after patching OCCT for bug OCC22436
            // (fix for OCCT is expected in service pack next to OCCT6.3sp12)
            if (aResShape.ShapeType() == TopAbs_COMPOUND) {
              int nbSub1 = 0;
              TopoDS_Shape currShape;
              TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
              for (; It.More(); It.Next()) {
                nbSub1++;
                currShape = It.Value();
              }
              if (nbSub1 == 1)
                aResShape = currShape;
            }
            // END workaround
            break;
          }

          for (Standard_Integer i = 1; i <= nbs; i++) {
            TopoDS_Shape aShape = aReader.Shape(i);
            if (aShape.IsNull()) {
              // THROW_SALOME_CORBA_EXCEPTION("Null shape in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM) ;
              //return aResShape;
              continue;
            }
            else {
              B.Add(compound, aShape);
            }
          }
        }
        if (aResShape.IsNull())
          aResShape = compound;

        // BEGIN: Store names of sub-shapes from file
        TopTools_IndexedMapOfShape anIndices;
        TopExp::MapShapes(aResShape, anIndices);

        Handle(Interface_InterfaceModel) Model = aReader.WS()->Model();
        Handle(XSControl_TransferReader) TR = aReader.WS()->TransferReader();
        if (!TR.IsNull()) {
          Handle(Transfer_TransientProcess) TP = TR->TransientProcess();
          Handle(Standard_Type) tPD  = STANDARD_TYPE(StepBasic_ProductDefinition);
          Handle(Standard_Type) tShape  = STANDARD_TYPE(StepShape_TopologicalRepresentationItem);
          Handle(Standard_Type) tGeom  = STANDARD_TYPE(StepGeom_GeometricRepresentationItem);

          Standard_Integer nb = Model->NbEntities();
          for (Standard_Integer ie = 1; ie <= nb; ie++) {
            Handle(Standard_Transient) enti = Model->Value(ie);
            Handle(TCollection_HAsciiString) aName;
            if ( enti->IsKind( tShape ) || enti->IsKind(tGeom))
            {
              aName = Handle(StepRepr_RepresentationItem)::DownCast(enti)->Name();
            }
            else if (enti->DynamicType() == tPD)
            {
              Handle(StepBasic_ProductDefinition) PD =
                Handle(StepBasic_ProductDefinition)::DownCast(enti);
              if (PD.IsNull()) continue;

              Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct();
              aName = Prod->Name();
            }
            else
            {
              continue;
            }
            if ( aName->UsefullLength() < 1 )
              continue;
            // skip 'N0NE' name
            if ( aName->UsefullLength() == 4 &&
                 toupper (aName->Value(1)) == 'N' &&
                 toupper (aName->Value(2)) == 'O' &&
                 toupper (aName->Value(3)) == 'N' &&
                 toupper (aName->Value(4)) == 'E')
              continue;

            // special check to pass names like "Open CASCADE STEP translator 6.3 1"
            TCollection_AsciiString aSkipName ("Open CASCADE STEP translator");
            if (aName->Length() >= aSkipName.Length()) {
              if (aName->String().SubString(1, aSkipName.Length()).IsEqual(aSkipName))
                continue;
            }
            TCollection_ExtendedString aNameExt (aName->ToCString());

            // find target shape
            Handle(Transfer_Binder) binder = TP->Find(enti);
            if (binder.IsNull()) continue;
            TopoDS_Shape S = TransferBRep::ShapeResult(binder);
            if (S.IsNull()) continue;

            // as PRODUCT can be included in the main shape
            // several times, we look here for all iclusions.
            Standard_Integer isub, nbSubs = anIndices.Extent();
            for (isub = 1; isub <= nbSubs; isub++)
            {
              TopoDS_Shape aSub = anIndices.FindKey(isub);
              if (aSub.IsPartner(S)) {
                TDF_Label L;
                if (enti->IsKind(tGeom)) {
                  // check all named shapes using iterator
                  TDF_ChildIDIterator anIt (theShapeLabel, TDataStd_Name::GetID(), Standard_True);
                  for (; anIt.More(); anIt.Next()) {
                    Handle(TDataStd_Name) nameAttr =
                      Handle(TDataStd_Name)::DownCast(anIt.Value());
                    if (nameAttr.IsNull()) continue;
                    TDF_Label Lab = nameAttr->Label();
                    Handle(TNaming_NamedShape) shAttr; 
                    if (Lab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) && shAttr->Get().IsEqual(aSub))
                      L = Lab;
                  }
                }
                // create label and set shape
                if (L.IsNull())
                {
                  TDF_TagSource aTag;
                  L = aTag.NewChild(theShapeLabel);
                  TNaming_Builder tnBuild (L);
                  //tnBuild.Generated(S);
                  tnBuild.Generated(aSub);
                }
                // set a name
                TDataStd_Name::Set(L, aNameExt);
              }
            }
          }
        }
        // END: Store names
      }
      else {
//        switch (status) {
//        case IFSelect_RetVoid:
//          theError = "Nothing created or No data to process";
//          break;
//        case IFSelect_RetError:
//          theError = "Error in command or input data";
//          break;
//        case IFSelect_RetFail:
//          theError = "Execution was run, but has failed";
//          break;
//        case IFSelect_RetStop:
//          theError = "Execution has been stopped. Quite possible, an exception was raised";
//          break;
//        default:
//          break;
//        }
        theError = "Wrong format of the imported file. Can't import file.";
        aResShape.Nullify();
      }
    }
    catch (Standard_Failure) {
      Handle(Standard_Failure) aFail = Standard_Failure::Caught();
      theError = aFail->GetMessageString();
      aResShape.Nullify();
    }
    // Return previous locale
    return aResShape;
  }
Esempio n. 13
0
void CmdPartDesignChamfer::activated(int iMsg)
{
    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();

    if (selection.size() != 1) {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
            QObject::tr("Select an edge, face or body. Only one body is allowed."));
        return;
    }

    if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"),
            QObject::tr("Chamfer works only on parts"));
        return;
    }

    Part::Feature *base = static_cast<Part::Feature*>(selection[0].getObject());

    const Part::TopoShape& TopShape = base->Shape.getShape();

    if (TopShape._Shape.IsNull()){
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
            QObject::tr("Shape of selected part is empty"));
        return;
    }

    TopTools_IndexedMapOfShape mapOfEdges;
    TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
    TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
    TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges);

    std::vector<std::string> SubNames = std::vector<std::string>(selection[0].getSubNames());

    int i = 0;

    while(i < SubNames.size())
    {
        std::string aSubName = static_cast<std::string>(SubNames.at(i));

        if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") {
            TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str()));
            const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge);

            if(los.Extent() != 2)
            {
                SubNames.erase(SubNames.begin()+i);
                continue;
            }

            const TopoDS_Shape& face1 = los.First();
            const TopoDS_Shape& face2 = los.Last();
            GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge),
                                                       TopoDS::Face(face1),
                                                       TopoDS::Face(face2));
            if (cont != GeomAbs_C0) {
                SubNames.erase(SubNames.begin()+i);
                continue;
            }

            i++;
        }
        else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") {
            TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str()));

            TopTools_IndexedMapOfShape mapOfFaces;
            TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces);

            for(int j = 1; j <= mapOfFaces.Extent(); ++j) {
                TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j));

                int id = mapOfEdges.FindIndex(edge);

                std::stringstream buf;
                buf << "Edge";
                buf << id;

                if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end())
                {
                    SubNames.push_back(buf.str());
                }

            }

            SubNames.erase(SubNames.begin()+i);
        }
        // empty name or any other sub-element
        else {
            SubNames.erase(SubNames.begin()+i);
        }
    }

    if (SubNames.size() == 0) {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
        QObject::tr("No chamfer possible on selected faces/edges"));
        return;
    }

    std::string SelString;
    SelString += "(App.";
    SelString += "ActiveDocument";//getObject()->getDocument()->getName();
    SelString += ".";
    SelString += selection[0].getFeatName();
    SelString += ",[";
    for(std::vector<std::string>::const_iterator it = SubNames.begin();it!=SubNames.end();++it){
        SelString += "\"";
        SelString += *it;
        SelString += "\"";
        if(it != --SubNames.end())
            SelString += ",";
    }
    SelString += "])";

    std::string FeatName = getUniqueObjectName("Chamfer");

    openCommand("Make Chamfer");
    doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Chamfer\",\"%s\")",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str());
    doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName());
    doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());

    copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName());
    copyVisual(FeatName.c_str(), "LineColor",  selection[0].getFeatName());
    copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName());
}