Example #1
0
/// Create a ChBodyAuxRef with assets for the given TopoDS_Shape
std::shared_ptr<ChBodyAuxRef> ChCascadeDoc::CreateBodyFromShape(
                const TopoDS_Shape& mshape,   ///< pass the shape here
                const double density          ///< pass the density here
                )
{
    std::shared_ptr<ChBodyAuxRef> mbody(new ChBodyAuxRef);
    
    chrono::ChFrame<> frame_ref_to_abs;

    TopLoc_Location loc_shape_to_abs = mshape.Location();
    chrono::cascade::ChCascadeDoc::FromCascadeToChrono(loc_shape_to_abs, frame_ref_to_abs);   

    TopoDS_Shape objshape = mshape;
    objshape.Location(TopLoc_Location());  // Reset shape location to local ref csys (identity).

    chrono::ChVector<> mcog;
    chrono::ChVector<> minertiaXX;
    chrono::ChVector<> minertiaXY;
    double mvol;
    double mmass;
    chrono::cascade::ChCascadeDoc::GetVolumeProperties(objshape, density, mcog, minertiaXX, minertiaXY, mvol, mmass);

    mbody->SetFrame_REF_to_abs(frame_ref_to_abs);

    //mbody->SetFrame_COG_to_REF(frame_ref_to_abs.Invert() * mcog );

    chrono::ChFrame<>* frame_cog_to_ref = (chrono::ChFrame<>*)mbody.get();
    frame_cog_to_ref->SetPos(mcog);
    frame_cog_to_ref->SetRot(chrono::QUNIT);

    return mbody;
}
Example #2
0
/// Create a ChBodyAuxRef with assets for the given TopoDS_Shape
std::shared_ptr<ChBodyAuxRef> ChCascadeDoc::CreateBodyFromShape(
                const TopoDS_Shape& mshape,   ///< pass the shape here
                const double density,         ///< pass the density here
				const bool collide,	
				const bool visual_asset
                )
{
    std::shared_ptr<ChBodyAuxRef> mbody(new ChBodyAuxRef);
    
    chrono::ChFrame<> frame_ref_to_abs;

    TopLoc_Location loc_shape_to_abs = mshape.Location();
    chrono::cascade::ChCascadeDoc::FromCascadeToChrono(loc_shape_to_abs, frame_ref_to_abs);   

    TopoDS_Shape objshape = mshape;
    objshape.Location(TopLoc_Location());  // Reset shape location to local ref csys (identity).

    chrono::ChVector<> mcog;
    chrono::ChVector<> minertiaXX;
    chrono::ChVector<> minertiaXY;
    double mvol;
    double mmass;
    chrono::cascade::ChCascadeDoc::GetVolumeProperties(objshape, density, mcog, minertiaXX, minertiaXY, mvol, mmass);

	// Set mass and COG and REF references
	mbody->SetDensity((float)density);
	mbody->SetMass(mmass);
	mbody->SetInertiaXX(minertiaXX);
	mbody->SetInertiaXY(minertiaXY);
	mbody->SetFrame_REF_to_abs(frame_ref_to_abs);

	chrono::ChFrame<> frame_cog_to_ref;
	frame_cog_to_ref.SetPos(mcog);
	frame_cog_to_ref.SetRot(chrono::QUNIT);
	mbody->SetFrame_COG_to_REF(frame_cog_to_ref);

	// Add a visualization asset if needed
	if (visual_asset) {
		auto trimesh = std::make_shared<geometry::ChTriangleMeshConnected>();
		ChCascadeMeshTools::fillTriangleMeshFromCascade(*trimesh, objshape);

		auto trimesh_shape = std::make_shared<ChTriangleMeshShape>();
		trimesh_shape->SetMesh(trimesh);
		mbody->AddAsset(trimesh_shape);

		// Add a collision shape if needed
		if (collide) {
			mbody->GetCollisionModel()->ClearModel();
			mbody->GetCollisionModel()->AddTriangleMesh(trimesh, false, false);
			mbody->GetCollisionModel()->BuildModel();
			mbody->SetCollide(true);
		}
	}

    return mbody;
}
Example #3
0
TopoDS_Shape Subassembly::lookupShape ( QVector<uint>& id_path ) const
{
  TopoDS_Shape shape;

  if ( subassembly_->id() == id_path[0] ) {
    id_path.erase( id_path.begin() );
    shape = subassembly_->lookupShape( id_path );
    shape.Location( location_ * shape.Location() );
  }

  return shape;
}
Example #4
0
//=======================================================================
//function : GetPosition
//purpose  :
//=======================================================================
gp_Ax3 GEOMUtils::GetPosition (const TopoDS_Shape& theShape)
{
  gp_Ax3 aResult;

  if (theShape.IsNull())
    return aResult;

  // Axes
  aResult.Transform(theShape.Location().Transformation());
  if (theShape.ShapeType() == TopAbs_FACE) {
    Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape));
    if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
      Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
      gp_Pln aPln = aGPlane->Pln();
      aResult = aPln.Position();
      // In case of reverse orinetation of the face invert the plane normal
      // (the face's normal does not mathc the plane's normal in this case)
      if(theShape.Orientation() == TopAbs_REVERSED)
      {
        gp_Dir Vx =  aResult.XDirection();
        gp_Dir N  =  aResult.Direction().Mirrored(Vx);
        gp_Pnt P  =  aResult.Location();
        aResult = gp_Ax3(P, N, Vx);
      }
    }
  }

  // Origin
  gp_Pnt aPnt;

  TopAbs_ShapeEnum aShType = theShape.ShapeType();

  if (aShType == TopAbs_VERTEX) {
    aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
  }
  else {
    if (aShType == TopAbs_COMPOUND) {
      aShType = GetTypeOfSimplePart(theShape);
    }

    GProp_GProps aSystem;
    if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE)
      BRepGProp::LinearProperties(theShape, aSystem);
    else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL)
      BRepGProp::SurfaceProperties(theShape, aSystem);
    else
      BRepGProp::VolumeProperties(theShape, aSystem);

    aPnt = aSystem.CentreOfMass();
  }

  aResult.SetLocation(aPnt);

  return aResult;
}
Example #5
0
TopoDS_Shape Subassembly::lookupShape ( QStringList& path_components ) const
{
  // The front path component is the name of a figure with ".type" appended
  // to it.
  int dot_pos = path_components.front().lastIndexOf( '.' );
  QString name = path_components.front().left( dot_pos );
  QString type = path_components.front().right( path_components.front().length()
						- dot_pos - 1 );
  TopoDS_Shape shape;

  if ( subassembly_->name() == name && subassembly_->type() == type ) {
    path_components.erase( path_components.begin() );
    // The shape returned here must be modified by the transformation
    // of the subassembly.
    shape = subassembly_->lookupShape( path_components );
    shape.Location( location_ * shape.Location() );
  }

  return shape;
}
Example #6
0
	virtual bool ForShape(TopoDS_Shape& mshape, TopLoc_Location& mloc, char* mname, int mlevel, TDF_Label& mlabel)
	{
		for (int i=0; i<mlevel; i++) GetLog()<< "  ";
		GetLog() << "-Name :" << mname;
		
		if (mlevel==0) GetLog() << " (root)";
		GetLog() << "\n";

		for (int i=0; i<mlevel; i++) GetLog()<< "  ";
		gp_XYZ mtr = mloc.Transformation().TranslationPart();
		GetLog() << "      pos at: "<< mtr.X() <<" "<< mtr.Y() << " "<<mtr.Z() <<" (absolute) \n";
		for (int i=0; i<mlevel; i++) GetLog()<< "  ";
		gp_XYZ mtr2 = mshape.Location().Transformation().TranslationPart();
		GetLog() << "      pos at: "<< mtr2.X() <<" "<< mtr2.Y() << " "<<mtr2.Z() <<" (.Location)\n";

		return true;
	}
Example #7
0
	virtual bool ForShape(TopoDS_Shape& mshape, TopLoc_Location& mloc, char* mname, int mlevel, TDF_Label& mlabel)
	{
		if (this->level_names.size() > mlevel)
		{
			if ( wildcard_compare(level_names[mlevel].c_str(), mname )) 
			{
				if (level_copy[mlevel] != -2)
				{
					level_copy[mlevel] = level_copy[mlevel]-1;
					if (level_copy[mlevel] < -1) 
						level_copy[mlevel] = -1;
				}
				
				if ((level_copy[mlevel] == 0) || (level_copy[mlevel] == -2))
				{
					if (mlevel == this->level_names.size()-1)
					{
						// Found!!!

						if (this->set_location_to_root)
							mshape.Location(mloc);

						// For single istance: only 1st found shape is considered
						if (!res_found)
						{
							res_found = true;
							res_shape = mshape;
							res_loc   = mloc;
							res_level = mlevel;
							res_label = mlabel;
						}

						// Add to the shape compound, for multiple results
						aBuilder.Add(res_comp, mshape);
					}
					return true; // proceed!
				}
				return false;  // break, matching name but not #ID, not needed to go deeper in levels
			} 
			return false; // break, not matching, not needed to go deeper in levels
		}
		else
			return false; // break, not needed to go deeper in levels than in string wildcard
	}
//================================================================
// Function : TexturesExt_Presentation::sampleKitchen
// Purpose  : kitchen with texturized items in it.
//================================================================
void TexturesExt_Presentation::sampleKitchen()
{
  TopoDS_Shape aShape;

  if (!loadShape(aShape, "Kitchen\\Room.brep"))
    return;

  gp_Trsf aTrsf;
  gp_Ax3 NewCoordSystem (gp_Pnt(-1,-1, -1),gp_Dir(0,0,1));
  gp_Ax3 CurrentCoordSystem(gp_Pnt(0,0,0),gp_Dir(0,0,1));
  aTrsf.SetDisplacement(CurrentCoordSystem, NewCoordSystem);
  aShape.Location(TopLoc_Location(aTrsf));

  moveScale(aShape);

  // draw kitchen room whithout one wall (to better see the insides)
  TopTools_IndexedMapOfShape aFaces;
  TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);  
  Standard_Integer nbFaces = aFaces.Extent();

  // create a wooden kitchen floor
  // the floor's face will be textured with texture from chataignier.gif
  DISP(Texturize(aFaces(5),"plancher.gif",1,1,2,1));

  // texturize other faces of the room with texture from wallpaper.gif (walls)
  DISP(Texturize(aFaces(1),"wallpaper.gif",1,1,8,6));
  DISP(Texturize(aFaces(3),"wallpaper.gif",1,1,8,6));
  DISP(Texturize(aFaces(4),"wallpaper.gif",1,1,8,6));

//  DISP(drawShape(aFaces(1), Quantity_NOC_LIGHTPINK, Standard_False));
//  DISP(drawShape(aFaces(3), Quantity_NOC_LIGHTPINK, Standard_False));
//  DISP(drawShape(aFaces(4), Quantity_NOC_LIGHTPINK, Standard_False));

  // texturize furniture items with "wooden" texture
  if (loadShape(aShape, "Kitchen\\MODERN_Table_1.brep"))
  {
    moveScale(aShape);
    DISP(Texturize(aShape, "chataignier.gif"));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Chair_1.brep"))
  {
    moveScale(aShape);
    DISP(Texturize(aShape, "chataignier.gif"));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Cooker_1.brep"))
  {
    moveScale(aShape);

    aFaces.Clear();
    TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);  
    nbFaces = aFaces.Extent();

    for (Standard_Integer i = 1; i <= nbFaces; i++)
    {
      if (i >= 59)
        DISP(drawShape(aFaces(i), Graphic3d_NOM_STEEL, Standard_False));
      else if (i >= 29)
        DISP(drawShape(aFaces(i), Graphic3d_NOM_ALUMINIUM, Standard_False));
      else if (i == 28)
        DISP(Texturize(aFaces(i), "cookerplate.gif"));
      else  
        DISP(Texturize(aFaces(i), "chataignier.gif"));
    }
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Cooker_1_opened.brep"))
  {
    moveScale(aShape);
    DISP(Texturize(aShape, "chataignier.gif"));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Exhaust_1.brep"))
  {
    moveScale(aShape);
    DISP(drawShape(aShape, Graphic3d_NOM_STONE, Standard_False));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_MVCooker_1.brep"))
  {
    moveScale(aShape);
    DISP(drawShape(aShape, Graphic3d_NOM_SILVER, Standard_False));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_MVCooker_1_opened.brep"))
  {
    moveScale(aShape);
    DISP(drawShape(aShape, Graphic3d_NOM_SILVER, Standard_False));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Sink_1.brep"))
  {
    moveScale(aShape);

    aFaces.Clear();
    TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);  
    nbFaces = aFaces.Extent();

    for (Standard_Integer i = 1; i <= nbFaces; i++)
    {
      if (i < 145)
        DISP(drawShape(aFaces(i), Graphic3d_NOM_ALUMINIUM, Standard_False));
      else if (i == 145)
        DISP(Texturize(aFaces(i), "cookerplate.gif"));
      else  
        DISP(Texturize(aFaces(i), "chataignier.gif"));
    }
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Sink_1_opened.brep"))
  {
    moveScale(aShape);
    DISP(Texturize(aShape, "chataignier.gif"));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Refrigerator_1.brep"))
  {
    moveScale(aShape);
    DISP(drawShape(aShape, Graphic3d_NOM_CHROME, Standard_False));
  }
  if (loadShape(aShape, "Kitchen\\MODERN_Refrigerator_1_opened.brep"))
  {
    moveScale(aShape);
    DISP(drawShape(aShape, Graphic3d_NOM_CHROME, Standard_False));
  }

  getViewer()->Update();
}
Example #9
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);
        }
    }
}
//=======================================================================
//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;
}
Example #11
0
App::DocumentObjectExecReturn *RuledSurface::execute(void)
{
    try {
        App::DocumentObjectExecReturn* ret;

        // get the first input shape
        TopoDS_Shape S1;
        ret = getShape(Curve1, S1);
        if (ret) return ret;

        // get the second input shape
        TopoDS_Shape S2;
        ret = getShape(Curve2, S2);
        if (ret) return ret;

        // check for expected type
        if (S1.IsNull() || S2.IsNull())
            return new App::DocumentObjectExecReturn("Linked shapes are empty.");

        if (S1.ShapeType() != TopAbs_EDGE && S1.ShapeType() != TopAbs_WIRE)
            return new App::DocumentObjectExecReturn("Linked shape is neither edge nor wire.");

        if (S2.ShapeType() != TopAbs_EDGE && S2.ShapeType() != TopAbs_WIRE)
            return new App::DocumentObjectExecReturn("Linked shape is neither edge nor wire.");

        // https://forum.freecadweb.org/viewtopic.php?f=8&t=24052
        //
        // if both shapes are sub-elements of one common shape then the fill algorithm
        // leads to problems if the shape has set a placement
        // The workaround is to reset the placement before calling BRepFill and then
        // applying the placement to the output shape
        TopLoc_Location Loc;
        if (Curve1.getValue() == Curve2.getValue()) {
            Loc = S1.Location();
            if (!Loc.IsIdentity() && Loc == S2.Location()) {
                S1.Location(TopLoc_Location());
                S2.Location(TopLoc_Location());
            }
        }

        // make both shapes to have the same type
        Standard_Boolean isWire = Standard_False;
        if (S1.ShapeType() == TopAbs_WIRE)
            isWire = Standard_True;

        if (isWire) {
            if (S2.ShapeType() == TopAbs_EDGE)
                S2 = BRepLib_MakeWire(TopoDS::Edge(S2));
        }
        else {
            // S1 is an edge, if S2 is a wire convert S1 to a wire, too
            if (S2.ShapeType() == TopAbs_WIRE) {
                S1 = BRepLib_MakeWire(TopoDS::Edge(S1));
                isWire = Standard_True;
            }
        }

        if (Orientation.getValue() == 0) {
            // Automatic
            Handle(Adaptor3d_HCurve) a1;
            Handle(Adaptor3d_HCurve) a2;
            if (!isWire) {
                BRepAdaptor_Curve adapt1(TopoDS::Edge(S1));
                BRepAdaptor_Curve adapt2(TopoDS::Edge(S2));
                a1 = new BRepAdaptor_HCurve(adapt1);
                a2 = new BRepAdaptor_HCurve(adapt2);
            }
            else {
                BRepAdaptor_CompCurve adapt1(TopoDS::Wire(S1));
                BRepAdaptor_CompCurve adapt2(TopoDS::Wire(S2));
                a1 = new BRepAdaptor_HCompCurve(adapt1);
                a2 = new BRepAdaptor_HCompCurve(adapt2);
            }

            if (!a1.IsNull() && !a2.IsNull()) {
                // get end points of 1st curve
                Standard_Real first, last;
                first = a1->FirstParameter();
                last = a1->LastParameter();
                if (S1.Closed())
                    last = (first + last)/2;
                gp_Pnt p1 = a1->Value(first);
                gp_Pnt p2 = a1->Value(last);
                if (S1.Orientation() == TopAbs_REVERSED) {
                    std::swap(p1, p2);
                }

                // get end points of 2nd curve
                first = a2->FirstParameter();
                last = a2->LastParameter();
                if (S2.Closed())
                    last = (first + last)/2;
                gp_Pnt p3 = a2->Value(first);
                gp_Pnt p4 = a2->Value(last);
                if (S2.Orientation() == TopAbs_REVERSED) {
                    std::swap(p3, p4);
                }

                // Form two triangles (P1,P2,P3) and (P4,P3,P2) and check their normals.
                // If the dot product is negative then it's assumed that the resulting face
                // is twisted, hence the 2nd edge is reversed.
                gp_Vec v1(p1, p2);
                gp_Vec v2(p1, p3);
                gp_Vec n1 = v1.Crossed(v2);

                gp_Vec v3(p4, p3);
                gp_Vec v4(p4, p2);
                gp_Vec n2 = v3.Crossed(v4);

                if (n1.Dot(n2) < 0) {
                    S2.Reverse();
                }
            }
        }
        else if (Orientation.getValue() == 2) {
            // Reverse
            S2.Reverse();
        }

        TopoDS_Shape ruledShape;
        if (!isWire) {
            ruledShape = BRepFill::Face(TopoDS::Edge(S1), TopoDS::Edge(S2));
        }
        else {
            ruledShape = BRepFill::Shell(TopoDS::Wire(S1), TopoDS::Wire(S2));
        }

        // re-apply the placement in case we reset it
        if (!Loc.IsIdentity())
            ruledShape.Move(Loc);
        Loc = ruledShape.Location();

        if (!Loc.IsIdentity()) {
            // reset the placement of the shape because the Placement
            // property will be changed
            ruledShape.Location(TopLoc_Location());
            Base::Matrix4D transform;
            TopoShape::convertToMatrix(Loc.Transformation(), transform);
            this->Placement.setValue(Base::Placement(transform));
        }

        this->Shape.setValue(ruledShape);
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure& e) {

        return new App::DocumentObjectExecReturn(e.GetMessageString());
    }
    catch (...) {
        return new App::DocumentObjectExecReturn("General error in RuledSurface::execute()");
    }
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

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

  TopoDS_Shape aShape;

  if (aType == POSITION_SHAPE || aType == POSITION_SHAPE_COPY) {
    Handle(GEOM_Function) aRefShape = aCI.GetShape();
    Handle(GEOM_Function) aRefStartLCS = aCI.GetStartLCS();
    Handle(GEOM_Function) aRefEndLCS = aCI.GetEndLCS();

    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    TopoDS_Shape aShapeStartLCS = aRefStartLCS->GetValue();
    TopoDS_Shape aShapeEndLCS = aRefEndLCS->GetValue();

    if (aShapeBase.IsNull() || aShapeStartLCS.IsNull() ||
        aShapeEndLCS.IsNull() || aShapeEndLCS.ShapeType() != TopAbs_FACE)
      return 0;

    gp_Trsf aTrsf;
    gp_Ax3 aStartAx3, aDestAx3;

    // End LCS
    aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS);

    // Start LCS
    aStartAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeStartLCS);

    // Set transformation
    aTrsf.SetDisplacement(aStartAx3, aDestAx3);

    // Perform transformation
    BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False);
    aShape = aBRepTrsf.Shape();
  }
  else if (aType == POSITION_SHAPE_FROM_GLOBAL ||
           aType == POSITION_SHAPE_FROM_GLOBAL_COPY) {
    Handle(GEOM_Function) aRefShape = aCI.GetShape();
    Handle(GEOM_Function) aRefEndLCS = aCI.GetEndLCS();

    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    TopoDS_Shape aShapeEndLCS = aRefEndLCS->GetValue();

    if (aShapeBase.IsNull() || aShapeEndLCS.IsNull() ||
        aShapeEndLCS.ShapeType() != TopAbs_FACE)
      return 0;

    gp_Trsf aTrsf;
    gp_Ax3 aStartAx3, aDestAx3;

    // End LCS
    aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS);

    // Set transformation
    aTrsf.SetDisplacement(aStartAx3, aDestAx3);

    // Perform transformation
    BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False);
    aShape = aBRepTrsf.Shape();
  }
  else if (aType == POSITION_ALONG_PATH) {
    Handle(GEOM_Function) aRefShape = aCI.GetShape();
    Handle(GEOM_Function) aPathShape = aCI.GetPath();
    Standard_Real aParameter = aCI.GetDistance();
    bool aReversed = aCI.GetReverse();
    if (aReversed)
      aParameter = 1 - aParameter;

    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    TopoDS_Shape aPath = aPathShape->GetValue();
    TopoDS_Wire aWire;

    if (aShapeBase.IsNull() || aPath.IsNull())
      return 0;

    if ( aPath.ShapeType() == TopAbs_EDGE ) {
      TopoDS_Edge anEdge = TopoDS::Edge(aPath);
      aWire = BRepBuilderAPI_MakeWire(anEdge); 
    }
    else if ( aPath.ShapeType() == TopAbs_WIRE)
      aWire = TopoDS::Wire(aPath);
    else
      return 0;

    Handle(GeomFill_TrihedronLaw) TLaw = new GeomFill_CorrectedFrenet();
    Handle(GeomFill_CurveAndTrihedron) aLocationLaw = new GeomFill_CurveAndTrihedron( TLaw );
    Handle(BRepFill_LocationLaw) aLocation = new BRepFill_Edge3DLaw(aWire, aLocationLaw);

    aLocation->TransformInCompatibleLaw( 0.01 );

    //Calculate a Parameter
    Standard_Real aFirstParam1 = 0, aLastParam1 = 0; // Parameters of the First edge
    Standard_Real aFirstParam2 = 0, aLastParam2 = 0; // Parameters of the Last edge
    aLocation->CurvilinearBounds(aLocation->NbLaw(), aFirstParam2, aLastParam2);

    if ( aLocation->NbLaw() > 1)
      aLocation->CurvilinearBounds(1, aFirstParam1, aLastParam1);
    else if ( aLocation->NbLaw() == 1 )
      aFirstParam1 = aFirstParam2;
    else
      return 0;

    Standard_Real aParam = (aFirstParam1 + (aLastParam2 - aFirstParam1)*aParameter );

    TopoDS_Shape CopyShape = aShapeBase;
    BRepFill_SectionPlacement Place( aLocation, aShapeBase );
    TopLoc_Location Loc2(Place.Transformation()), Loc1;
    Loc1 = CopyShape.Location();
    CopyShape.Location(Loc2.Multiplied(Loc1));

    aLocation->D0( aParam, CopyShape );
    aShape = CopyShape;
  }
  else
    return 0;

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}