Py::Object TopoShapeFacePy::getCenterOfMass(void) const
{
    GProp_GProps props;
    BRepGProp::SurfaceProperties(getTopoShapePtr()->getShape(), props);
    gp_Pnt c = props.CentreOfMass();
    return Py::Vector(Base::Vector3d(c.X(),c.Y(),c.Z()));
}
Py::Object TopoShapeEdgePy::getCenterOfMass(void) const
{
    GProp_GProps props;
    BRepGProp::LinearProperties(getTopoShapePtr()->_Shape, props);
    gp_Pnt c = props.CentreOfMass();
    return Py::Vector(Base::Vector3d(c.X(),c.Y(),c.Z()));
}
Exemplo n.º 3
0
Py::Object TopoShapeSolidPy::getMass(void) const
{
    GProp_GProps props;
    BRepGProp::VolumeProperties(getTopoShapePtr()->_Shape, props);
    double c = props.Mass();
    return Py::Float(c);
}
Exemplo n.º 4
0
double ProfileBased::getReversedAngle(const Base::Vector3d &b, const Base::Vector3d &v)
{
    try {
        Part::Feature* obj = getVerifiedObject();
        TopoDS_Shape sketchshape = getVerifiedFace();

        // get centre of gravity of the sketch face
        GProp_GProps props;
        BRepGProp::SurfaceProperties(sketchshape, props);
        gp_Pnt cog = props.CentreOfMass();
        Base::Vector3d p_cog(cog.X(), cog.Y(), cog.Z());
        // get direction to cog from its projection on the revolve axis
        Base::Vector3d perp_dir = p_cog - p_cog.Perpendicular(b, v);
        // get cross product of projection direction with revolve axis direction
        Base::Vector3d cross = v % perp_dir;
        // get sketch vector pointing away from support material
        Base::Placement SketchPos = obj->Placement.getValue();
        Base::Rotation SketchOrientation = SketchPos.getRotation();
        Base::Vector3d SketchNormal(0,0,1);
        SketchOrientation.multVec(SketchNormal,SketchNormal);

        return SketchNormal * cross;
    }
    catch (...) {
        return Reversed.getValue() ? 1 : 0;
    }
}
Py::Object TopoShapeFacePy::getMass(void) const
{
    GProp_GProps props;
    BRepGProp::SurfaceProperties(getTopoShapePtr()->getShape(), props);
    double c = props.Mass();
    return Py::Float(c);
}
Py::Dict TopoShapeFacePy::getPrincipalProperties(void) const
{
    GProp_GProps props;
    BRepGProp::SurfaceProperties(getTopoShapePtr()->getShape(), props);
    GProp_PrincipalProps pprops = props.PrincipalProperties();

    Py::Dict dict;
    dict.setItem("SymmetryAxis", Py::Boolean(pprops.HasSymmetryAxis() ? true : false));
    dict.setItem("SymmetryPoint", Py::Boolean(pprops.HasSymmetryPoint() ? true : false));
    Standard_Real lx,ly,lz;
    pprops.Moments(lx,ly,lz);
    Py::Tuple tuple(3);
    tuple.setItem(0, Py::Float(lx));
    tuple.setItem(1, Py::Float(ly));
    tuple.setItem(2, Py::Float(lz));
    dict.setItem("Moments",tuple);
    dict.setItem("FirstAxisOfInertia",Py::Vector(Base::convertTo
        <Base::Vector3d>(pprops.FirstAxisOfInertia())));
    dict.setItem("SecondAxisOfInertia",Py::Vector(Base::convertTo
        <Base::Vector3d>(pprops.SecondAxisOfInertia())));
    dict.setItem("ThirdAxisOfInertia",Py::Vector(Base::convertTo
        <Base::Vector3d>(pprops.ThirdAxisOfInertia())));

    Standard_Real Rxx,Ryy,Rzz;
    pprops.RadiusOfGyration(Rxx,Ryy,Rzz);
    Py::Tuple rog(3);
    rog.setItem(0, Py::Float(Rxx));
    rog.setItem(1, Py::Float(Ryy));
    rog.setItem(2, Py::Float(Rzz));
    dict.setItem("RadiusOfGyration",rog);
    return dict;
}
Exemplo n.º 7
0
//=======================================================================
//function : ShapeToDouble
//purpose  : used by CompareShapes::operator()
//=======================================================================
std::pair<double, double> GEOMUtils::ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
{
  // Computing of CentreOfMass
  gp_Pnt GPoint;
  double Len;

  if (S.ShapeType() == TopAbs_VERTEX) {
    GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
    Len = (double)S.Orientation();
  }
  else {
    GProp_GProps GPr;
    // BEGIN: fix for Mantis issue 0020842
    if (isOldSorting) {
      BRepGProp::LinearProperties(S, GPr);
    }
    else {
      if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
        BRepGProp::LinearProperties(S, GPr);
      }
      else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
        BRepGProp::SurfaceProperties(S, GPr);
      }
      else {
        BRepGProp::VolumeProperties(S, GPr);
      }
    }
    // END: fix for Mantis issue 0020842
    GPoint = GPr.CentreOfMass();
    Len = GPr.Mass();
  }

  double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
  return std::make_pair(dMidXYZ, Len);
}
Exemplo n.º 8
0
//-------------------------------------------------------------------------
// Purpose       : Returns the center of the Surface mass
//
//-------------------------------------------------------------------------
CubitVector OCCSurface::center_point()
{
  GProp_GProps myProps;
  BRepGProp::SurfaceProperties(*myTopoDSFace, myProps);
  gp_Pnt pt = myProps.CentreOfMass();
  CubitVector v(pt.X(),pt.Y(), pt.Z());
  return v; 
}
Exemplo n.º 9
0
void CShape::CalculateVolumeAndCentre()
{
	GProp_GProps System;
    BRepGProp::VolumeProperties(m_shape, System);
    m_volume = System.Mass();
	m_centre_of_mass = System.CentreOfMass();
	m_volume_found = true;
}
Exemplo n.º 10
0
// Returns the surface area of this fuselage
double CCPACSFuselage::GetSurfaceArea(void)
{
    const TopoDS_Shape& fusedSegments = GetLoft()->Shape();
    // Calculate surface area
    GProp_GProps System;
    BRepGProp::SurfaceProperties(fusedSegments, System);
    double myArea = System.Mass();
    return myArea;
}
Exemplo n.º 11
0
// Returns the volume of this fuselage
double CCPACSFuselage::GetVolume(void)
{
    const TopoDS_Shape& fusedSegments = GetLoft()->Shape();

    // Calculate volume
    GProp_GProps System;
    BRepGProp::VolumeProperties(fusedSegments, System);
    double myVolume = System.Mass();
    return myVolume;
}
Exemplo n.º 12
0
OCCStruct3d OCCFace::centreOfMass() {
    OCCStruct3d ret;
    GProp_GProps prop;
    BRepGProp::SurfaceProperties(this->getShape(), prop);
    gp_Pnt cg = prop.CentreOfMass();
    ret.x = cg.X();
    ret.y = cg.Y();
    ret.z = cg.Z();
    return ret;
}
Exemplo n.º 13
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;
}
Py::Object TopoShapeFacePy::getStaticMoments(void) const
{
    GProp_GProps props;
    BRepGProp::SurfaceProperties(getTopoShapePtr()->getShape(), props);
    Standard_Real lx,ly,lz;
    props.StaticMoments(lx,ly,lz);
    Py::Tuple tuple(3);
    tuple.setItem(0, Py::Float(lx));
    tuple.setItem(1, Py::Float(ly));
    tuple.setItem(2, Py::Float(lz));
    return tuple;
}
Exemplo n.º 15
0
DVec OCCFace::inertia() {
    DVec ret;
    GProp_GProps prop;
    BRepGProp::SurfaceProperties(this->getShape(), prop);
    gp_Mat mat = prop.MatrixOfInertia();
    ret.push_back(mat(1,1)); // Ixx
    ret.push_back(mat(2,2)); // Iyy
    ret.push_back(mat(3,3)); // Izz
    ret.push_back(mat(1,2)); // Ixy
    ret.push_back(mat(1,3)); // Ixz
    ret.push_back(mat(2,3)); // Iyz
    return ret;
}
Py::Object TopoShapeFacePy::getMatrixOfInertia(void) const
{
    GProp_GProps props;
    BRepGProp::SurfaceProperties(getTopoShapePtr()->getShape(), props);
    gp_Mat m = props.MatrixOfInertia();
    Base::Matrix4D mat;
    for (int i=0; i<3; i++) {
        for (int j=0; j<3; j++) {
            mat[i][j] = m(i+1,j+1);
        }
    }
    return Py::Matrix(mat);
}
Exemplo n.º 17
0
TEST(BRepGPropTestSuite, testComputeBoxVolume)
{
    // create a box, mixing integers and floats
    BRepPrimAPI_MakeBox my_box(10.,10.,10.);
    my_box.Build();
    ASSERT_TRUE(my_box.IsDone());
    // compute shape properties
    GProp_GProps prop;
    // a 10*10*10 cube should have a volume of 1000
    BRepGProp::VolumeProperties(my_box.Shape(), prop);
    ASSERT_GT(prop.Mass(),1000.-Precision::Confusion());
    ASSERT_LT(prop.Mass(),1001.+Precision::Confusion());
}
Exemplo n.º 18
0
TEST(BRepGPropTestSuite, testComputeBoxSurface)
{
    // create a box, mixing integers and floats
    BRepPrimAPI_MakeBox my_box(10.,10.,10.);
    my_box.Build();
    ASSERT_TRUE(my_box.IsDone());
    // compute shape properties
    GProp_GProps prop;
    // the surface should be 6 faces*10*10=600
    BRepGProp::SurfaceProperties(my_box.Shape(), prop);
    ASSERT_GT(prop.Mass(),600.-Precision::Confusion());
    ASSERT_LT(prop.Mass(),600.+Precision::Confusion());
}
Exemplo n.º 19
0
TEST(BRepGPropTestSuite, testComputeSphereVolume)
{
    // create a box, mixing integers and floats
    BRepPrimAPI_MakeSphere sphere(20.);
    sphere.Build();
    ASSERT_TRUE(sphere.IsDone());
    // compute shape properties
    GProp_GProps prop;
    // a sphere with a radius of 20 should have a volume of 
    // V = 4/3*pi*20*20*20 = 33510.321638291127
    BRepGProp::VolumeProperties(sphere.Shape(), prop);
    ASSERT_GT(prop.Mass(),33510.321638291127-Precision::Confusion());
    ASSERT_LT(prop.Mass(),33510.321638291127+Precision::Confusion());
}
Exemplo n.º 20
0
int main(int argc, char **argv){
    TopoDS_Shape shape;
    BRep_Builder builder;
    GProp_GProps prop;

    if (argc < 2)
    {
        std::cerr << "Usage: computeSurface file.brep" << std::endl;
        exit(1);
    }
    BRepTools::Read(shape, argv[1], builder);
    BRepGProp::SurfaceProperties(shape, prop);
    std::cout << "Total surface of all shapes: " << prop.Mass() << std::endl;
    return 0;
}
Exemplo n.º 21
0
bool DrawUtil::isZeroEdge(TopoDS_Edge e)
{
    TopoDS_Vertex vStart = TopExp::FirstVertex(e);
    TopoDS_Vertex vEnd = TopExp::LastVertex(e);
    bool result = isSamePoint(vStart,vEnd);
    if (result) {
        //closed edge will have same V's but non-zero length
        GProp_GProps props;
        BRepGProp::LinearProperties(e, props);
        double len = props.Mass();
        if (len > Precision::Confusion()) {
            result = false;
        }
    }
    return result;
}
Exemplo n.º 22
0
const std::list<gp_Trsf> Scaled::getTransformations(const std::vector<App::DocumentObject*> originals)
{
    double factor = Factor.getValue();
    if (factor < Precision::Confusion())
        throw Base::Exception("Scaling factor too small");
    int occurrences = Occurrences.getValue();
    if (occurrences < 2)
        throw Base::Exception("At least two occurrences required");

    double f = (factor - 1.0) / double(occurrences - 1);

    // Find centre of gravity of first original
    // FIXME: This method will NOT give the expected result for more than one original!
    Part::Feature* originalFeature = static_cast<Part::Feature*>(originals.front());
    TopoDS_Shape original;

    if (originalFeature->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) {
        PartDesign::Additive* addFeature = static_cast<PartDesign::Additive*>(originalFeature);
        original = addFeature->AddShape.getShape()._Shape;
    } else if (originalFeature->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
        PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(originalFeature);
        original = subFeature->SubShape.getShape()._Shape;
    }

    GProp_GProps props;
    BRepGProp::VolumeProperties(original,props);
    gp_Pnt cog = props.CentreOfMass();

    // Note: The original feature is NOT included in the list of transformations! Therefore
    // we start with occurrence number 1, not number 0
    std::list<gp_Trsf> transformations;
    gp_Trsf trans;
    transformations.push_back(trans); // identity transformation

    for (int i = 1; i < occurrences; i++) {
        trans.SetScale(cog, 1.0 + double(i) * f);
        transformations.push_back(trans);
    }

    return transformations;
}
Base::Vector3d Measurement::massCenter() const
{

    int numRefs =  References3D.getSize();
    if(!numRefs || measureType == Invalid)
        throw Base::Exception("Measurement - massCenter - Invalid References3D Provided");

    const std::vector<App::DocumentObject*> &objects = References3D.getValues();
    const std::vector<std::string> &subElements = References3D.getSubValues();


    GProp_GProps gprops = GProp_GProps();

    if(measureType == Volumes) {
        // Iterate through edges and calculate each length
        std::vector<App::DocumentObject*>::const_iterator obj = objects.begin();
        std::vector<std::string>::const_iterator subEl = subElements.begin();

        for (;obj != objects.end(); ++obj, ++subEl) {
            //const Part::Feature *refObj = static_cast<const Part::Feature*>((*obj));
            //const Part::TopoShape& refShape = refObj->Shape.getShape();

            // Compute inertia properties

            GProp_GProps props = GProp_GProps();
            BRepGProp::VolumeProperties(getShape((*obj), ""), props);
            gprops.Add(props);
            // Get inertia properties
        }

        //double mass = gprops.Mass();
        gp_Pnt cog = gprops.CentreOfMass();

        return Base::Vector3d(cog.X(), cog.Y(), cog.Z());

      } else {
          throw Base::Exception("Measurement - massCenter - Invalid References3D Provided");
      }
}
Exemplo n.º 24
0
//-------------------------------------------------------------------------
// Purpose       : Find centroid and volume for lumps and shells
//
// Special Notes : 
//
// Author       : Jane Hu  
//
// Creation Date : 11/30/07
//-------------------------------------------------------------------------
CubitStatus OCCBody::mass_properties( CubitVector& centroid, 
                                      double& volume )
{
  if( myShells.size() == 0 && myLumps.size() == 0)
    return CUBIT_FAILURE;
  GProp_GProps myProps;
  TopoDS_Shape* pshape = myTopoDSShape;
  if(!pshape || pshape->IsNull())//single lump or shell or surface
  {
    DLIList<Lump*> lumps = this->lumps();
    if (lumps.size() > 0)
      pshape = CAST_TO(lumps.get(), OCCLump)->get_TopoDS_Solid();
  } 
  if(!pshape || pshape->IsNull())
    return CUBIT_FAILURE;
 
  BRepGProp::VolumeProperties(*pshape, myProps);
  volume = myProps.Mass();
  gp_Pnt pt = myProps.CentreOfMass(); 
  centroid.set(pt.X(), pt.Y(), pt.Z());
  return CUBIT_SUCCESS;
}
Exemplo n.º 25
0
PyObject* TopoShapeSolidPy::getRadiusOfGyration(PyObject *args)
{
    PyObject *p,*d;
    if (!PyArg_ParseTuple(args, "O!O!",&Base::VectorPy::Type,&p
                                      ,&Base::VectorPy::Type,&d))
        return 0;
    Base::Vector3d pnt = Py::Vector(p,false).toVector();
    Base::Vector3d dir = Py::Vector(d,false).toVector();

    try {
        GProp_GProps props;
        BRepGProp::VolumeProperties(getTopoShapePtr()->getShape(), props);
        double r = props.RadiusOfGyration(gp_Ax1(Base::convertTo<gp_Pnt>(pnt),
                                                Base::convertTo<gp_Dir>(dir)));
        return PyFloat_FromDouble(r);
    }
    catch (Standard_Failure& e) {

        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
        return 0;
    }
}
bool Revolution::suggestReversed(void)
{
    try {
        updateAxis();

        Part::Part2DObject* sketch = getVerifiedSketch();
        std::vector<TopoDS_Wire> wires = getSketchWires();
        TopoDS_Shape sketchshape = makeFace(wires);

        Base::Vector3d b = Base.getValue();
        Base::Vector3d v = Axis.getValue();

        // get centre of gravity of the sketch face
        GProp_GProps props;
        BRepGProp::SurfaceProperties(sketchshape, props);
        gp_Pnt cog = props.CentreOfMass();
        Base::Vector3d p_cog(cog.X(), cog.Y(), cog.Z());
        // get direction to cog from its projection on the revolve axis
        Base::Vector3d perp_dir = p_cog - p_cog.Perpendicular(b, v);
        // get cross product of projection direction with revolve axis direction
        Base::Vector3d cross = v % perp_dir;
        // get sketch vector pointing away from support material
        Base::Placement SketchPos = sketch->Placement.getValue();
        Base::Rotation SketchOrientation = SketchPos.getRotation();
        Base::Vector3d SketchNormal(0,0,1);
        SketchOrientation.multVec(SketchNormal,SketchNormal);
        // simply convert double to float
        Base::Vector3d norm(SketchNormal.x, SketchNormal.y, SketchNormal.z);

        // return true if the angle between norm and cross is obtuse
        return norm * cross < 0.f;
    }
    catch (...) {
        return Reversed.getValue();
    }
}
//=======================================================================
//function : PointProperties
//purpose  :
//=======================================================================
void PointProperties(const TopoDS_Shape& aS, GProp_GProps& aGProps)
{
  Standard_Integer i, aNbS;
  Standard_Real aDensity;
  gp_Pnt aPX;
  TopTools_IndexedMapOfShape aMS;
  //
  aDensity=1.;
  //
  TopExp::MapShapes(aS, TopAbs_VERTEX, aMS);
  aNbS=aMS.Extent();
  for (i=1; i<=aNbS; ++i) {
    GEOMAlgo_GProps aGPropsX;
    //
    const TopoDS_Vertex& aVX=*((TopoDS_Vertex*)&aMS(i));
    aPX=BRep_Tool::Pnt(aVX);
    aGPropsX.SetMass(1.);
    aGPropsX.SetCG(aPX);
    aGProps.Add(aGPropsX, aDensity);
  }
}
Exemplo n.º 28
0
bool ChCascadeDoc::GetVolumeProperties(const TopoDS_Shape& mshape,	///< pass the shape here
						const double density,				///< pass the density here 
						ChVector<>& center_position,		///< get the position center, respect to shape pos.
						ChVector<>& inertiaXX,				///< get the inertia diagonal terms
						ChVector<>& inertiaXY,				///< get the inertia extradiagonal terms
						double& volume,						///< get the volume
						double& mass						///< get the mass
						)
{
	if (mshape.IsNull()) 
		return false;

	GProp_GProps mprops;
	GProp_GProps vprops;
	BRepGProp::VolumeProperties(mshape,mprops);
	BRepGProp::VolumeProperties(mshape,vprops);

	mprops.Add(mprops, density);

	mass = mprops.Mass();
	volume = vprops.Mass();
	gp_Pnt G = mprops.CentreOfMass ();
	gp_Mat I = mprops.MatrixOfInertia();

	center_position.x = G.X();
	center_position.y = G.Y();
	center_position.z = G.Z();

	inertiaXX.x = I(1,1);
	inertiaXX.y = I(2,2);
	inertiaXX.z = I(3,3);
	inertiaXY.x = I(1,2);
	inertiaXY.y = I(1,3);
	inertiaXY.z = I(2,3);

	return true;
}
Exemplo n.º 29
0
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_RotateDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  if (aFunction.IsNull()) return 0;

  GEOMImpl_IRotate RI(aFunction);
  gp_Trsf aTrsf;
  gp_Pnt aCP, aP1, aP2;
  Standard_Integer aType = aFunction->GetType();
  Handle(GEOM_Function) anOriginalFunction = RI.GetOriginal();
  if (anOriginalFunction.IsNull()) return 0;
  TopoDS_Shape aShape, anOriginal = anOriginalFunction->GetValue();
  if (anOriginal.IsNull()) return 0;

  if (aType == ROTATE || aType == ROTATE_COPY) {
    Handle(GEOM_Function) anAxis = RI.GetAxis();
    if (anAxis.IsNull()) return 0;
    TopoDS_Shape A = anAxis->GetValue();
    if (A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0;
    TopoDS_Edge anEdge = TopoDS::Edge(A);

    gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
    gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
    gp_Dir aDir(gp_Vec(aP1, aP2));
    gp_Ax1 anAx1(aP1, aDir);
    Standard_Real anAngle = RI.GetAngle();
    if (fabs(anAngle) < Precision::Angular()) anAngle += 2*PI; // NPAL19665,19769
    aTrsf.SetRotation(anAx1, anAngle);

    //NPAL18620: performance problem: multiple locations are accumulated
    //           in shape and need a great time to process
    //BRepBuilderAPI_Transform aTransformation(anOriginal, aTrsf, Standard_False);
    //aShape = aTransformation.Shape();
    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();
    //TopLoc_Location aLocRes (aTrsf * aTrsfOrig); // gp_Trsf::Multiply() has a bug
    aTrsfOrig.PreMultiply(aTrsf);
    TopLoc_Location aLocRes (aTrsfOrig);
    aShape = anOriginal.Located(aLocRes);
  }
  else if (aType ==  ROTATE_THREE_POINTS || aType == ROTATE_THREE_POINTS_COPY) {
    Handle(GEOM_Function) aCentPoint = RI.GetCentPoint();
    Handle(GEOM_Function) aPoint1 = RI.GetPoint1();
    Handle(GEOM_Function) aPoint2 = RI.GetPoint2();
    if(aCentPoint.IsNull() || aPoint1.IsNull() || aPoint2.IsNull()) return 0;
    TopoDS_Shape aCV = aCentPoint->GetValue();
    TopoDS_Shape aV1 = aPoint1->GetValue();
    TopoDS_Shape aV2 = aPoint2->GetValue();
    if(aCV.IsNull() || aCV.ShapeType() != TopAbs_VERTEX) return 0;
    if(aV1.IsNull() || aV1.ShapeType() != TopAbs_VERTEX) return 0;
    if(aV2.IsNull() || aV2.ShapeType() != TopAbs_VERTEX) return 0;

    aCP = BRep_Tool::Pnt(TopoDS::Vertex(aCV));
    aP1 = BRep_Tool::Pnt(TopoDS::Vertex(aV1));
    aP2 = BRep_Tool::Pnt(TopoDS::Vertex(aV2));

    gp_Vec aVec1 (aCP, aP1);
    gp_Vec aVec2 (aCP, aP2);
    gp_Dir aDir (aVec1 ^ aVec2);
    gp_Ax1 anAx1 (aCP, aDir);
    Standard_Real anAngle = aVec1.Angle(aVec2);
    if (fabs(anAngle) < Precision::Angular()) anAngle += 2*PI; // NPAL19665
    aTrsf.SetRotation(anAx1, anAngle);
    //NPAL18620: performance problem: multiple locations are accumulated
    //           in shape and need a great time to process
    //BRepBuilderAPI_Transform aTransformation(anOriginal, aTrsf, Standard_False);
    //aShape = aTransformation.Shape();
    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();
    //TopLoc_Location aLocRes (aTrsf * aTrsfOrig); // gp_Trsf::Multiply() has a bug
    aTrsfOrig.PreMultiply(aTrsf);
    TopLoc_Location aLocRes (aTrsfOrig);
    aShape = anOriginal.Located(aLocRes);
  }
  else if (aType == ROTATE_1D) {
    //Get direction
    Handle(GEOM_Function) anAxis = RI.GetAxis();
    if(anAxis.IsNull()) return 0;
    TopoDS_Shape A = anAxis->GetValue();
    if(A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0;
    TopoDS_Edge anEdge = TopoDS::Edge(A);

    gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
    gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
    gp_Dir D(gp_Vec(aP1, aP2));

    gp_Ax1 AX1(aP1, D);

    Standard_Integer nbtimes = RI.GetNbIter1();
    Standard_Real angle = 360.0/nbtimes;

    TopoDS_Compound aCompound;
    BRep_Builder B;
    B.MakeCompound( aCompound );

    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();

    for (int i = 0; i < nbtimes; i++ ) {
      if (i == 0) { // NPAL19665
        B.Add(aCompound, anOriginal);
      }
      else {
        aTrsf.SetRotation(AX1, i*angle/* * PI180 */);
        //TopLoc_Location aLocRes (aTrsf * aTrsfOrig); // gp_Trsf::Multiply() has a bug
        gp_Trsf aTrsfNew (aTrsfOrig);
        aTrsfNew.PreMultiply(aTrsf);
        TopLoc_Location aLocRes (aTrsfNew);
        B.Add(aCompound, anOriginal.Located(aLocRes));
      }
      //NPAL18620: performance problem: multiple locations are accumulated
      //           in shape and need a great time to process
      //BRepBuilderAPI_Transform aBRepTransformation(anOriginal, aTrsf, Standard_False);
      //B.Add(aCompound, aBRepTransformation.Shape());
    }

    aShape = aCompound;
  }
  else if (aType == ROTATE_2D) {
    //Get direction
    Handle(GEOM_Function) anAxis = RI.GetAxis();
    if(anAxis.IsNull()) return 0;
    TopoDS_Shape A = anAxis->GetValue();
    if(A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0;
    TopoDS_Edge anEdge = TopoDS::Edge(A);
    gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
    gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
    gp_Dir D(gp_Vec(aP1, aP2));

    gp_Ax1 AX1(aP1, D);

    gp_Trsf aTrsf1;
    gp_Trsf aTrsf2;
    gp_Trsf aTrsf3;

    gp_XYZ aDir2 = RI.GetDir2(); // can be set by previous execution
    if (aDir2.Modulus() < gp::Resolution()) {
      // Calculate direction as vector from the axis to the shape's center
    gp_Pnt P1;
    GProp_GProps System;

    if (anOriginal.ShapeType() == TopAbs_VERTEX) {
      P1 = BRep_Tool::Pnt(TopoDS::Vertex( anOriginal ));
    }
    else if ( anOriginal.ShapeType() == TopAbs_EDGE || anOriginal.ShapeType() == TopAbs_WIRE ) {
      BRepGProp::LinearProperties(anOriginal, System);
      P1 = System.CentreOfMass();
    }
    else if ( anOriginal.ShapeType() == TopAbs_FACE || anOriginal.ShapeType() == TopAbs_SHELL ) {
      BRepGProp::SurfaceProperties(anOriginal, System);
      P1 = System.CentreOfMass();
    }
    else {
      BRepGProp::VolumeProperties(anOriginal, System);
      P1 = System.CentreOfMass();
    }

    Handle(Geom_Line) Line = new Geom_Line(AX1);
    GeomAPI_ProjectPointOnCurve aPrjTool( P1, Line );
    gp_Pnt P2 = aPrjTool.NearestPoint();

    if ( P1.IsEqual(P2, Precision::Confusion() ) ) return 0;

    aDir2 = gp_XYZ(P1.X()-P2.X(), P1.Y()-P2.Y(), P1.Z()-P2.Z());

    // Attention: this abnormal action is done for good working of
    // TransformLikeOther(), used by RestoreSubShapes functionality
    RI.SetDir2(aDir2);
    }

    gp_Vec Vec (aDir2);
    Vec.Normalize();

    gp_Vec elevVec(D);
    elevVec.Normalize();

    Standard_Integer nbtimes2 = RI.GetNbIter2();
    Standard_Integer nbtimes1 = RI.GetNbIter1();
    Standard_Real step = RI.GetStep();
    Standard_Real elevationstep = RI.GetElevationStep();
    Standard_Real ang = RI.GetAngle();

    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();

    gp_Vec aVec;
    TopoDS_Compound aCompound;
    BRep_Builder B;
    B.MakeCompound( aCompound );

    Standard_Real DX, DY, DZ;

    for (int i = 0; i < nbtimes2; i++ ) {
      if (i != 0) {
        DX = i * step * Vec.X();
        DY = i * step * Vec.Y();
        DZ = i * step * Vec.Z();
        aVec.SetCoord( DX, DY, DZ );
        aTrsf1.SetTranslation(aVec);
      }
      for (int j = 0; j < nbtimes1; j++ ) {
        if (j == 0) { // NPAL19665
          TopLoc_Location aLocRes (aTrsf1 * aTrsfOrig);
          B.Add(aCompound, anOriginal.Located(aLocRes));
        }
        else {
          DX = j * elevationstep * elevVec.X();
          DY = j * elevationstep * elevVec.Y();
          DZ = j * elevationstep * elevVec.Z();
          aVec.SetCoord( DX, DY, DZ );
          aTrsf3.SetTranslation(aVec);

          aTrsf2.SetRotation(AX1, j*ang /* * PI180 */ );
          //TopLoc_Location aLocRes (aTrsf2 * aTrsf1 * aTrsfOrig); // gp_Trsf::Multiply() has a bug
          gp_Trsf aTrsfNew (aTrsfOrig);
          aTrsfNew.PreMultiply(aTrsf1);
          aTrsfNew.PreMultiply(aTrsf2);
          aTrsfNew.PreMultiply(aTrsf3);
          TopLoc_Location aLocRes (aTrsfNew);
          B.Add(aCompound, anOriginal.Located(aLocRes));
        }
        //NPAL18620: performance problem: multiple locations are accumulated
        //           in shape and need a great time to process
        //BRepBuilderAPI_Transform aBRepTrsf1 (anOriginal, aTrsf1, Standard_False);
        //BRepBuilderAPI_Transform aBRepTrsf2 (aBRepTrsf1.Shape(), aTrsf2, Standard_False);
        //B.Add(aCompound, aBRepTrsf2.Shape());
      }
    }

    aShape = aCompound;
  }
  else return 0;


  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
Exemplo n.º 30
0
bool Constraint::getPoints(std::vector<Base::Vector3d> &points, std::vector<Base::Vector3d> &normals, int * scale) const
{
    std::vector<App::DocumentObject*> Objects = References.getValues();
    std::vector<std::string> SubElements = References.getSubValues();

    // Extract geometry from References
    TopoDS_Shape sh;

    for (std::size_t i = 0; i < Objects.size(); i++) {
        App::DocumentObject* obj = Objects[i];
        Part::Feature* feat = static_cast<Part::Feature*>(obj);
        const Part::TopoShape& toposhape = feat->Shape.getShape();
        if (toposhape.isNull())
            return false;

        sh = toposhape.getSubShape(SubElements[i].c_str());

        if (sh.ShapeType() == TopAbs_VERTEX) {
            const TopoDS_Vertex& vertex = TopoDS::Vertex(sh);
            gp_Pnt p = BRep_Tool::Pnt(vertex);
            points.push_back(Base::Vector3d(p.X(), p.Y(), p.Z()));
            normals.push_back(NormalDirection.getValue());
            //OvG: Scale by whole object mass in case of a vertex
            GProp_GProps props;
            BRepGProp::VolumeProperties(toposhape.getShape(), props);
            double lx = props.Mass();
            *scale = this->calcDrawScaleFactor(sqrt(lx)*0.5); //OvG: setup draw scale for constraint
        }
        else if (sh.ShapeType() == TopAbs_EDGE) {
            BRepAdaptor_Curve curve(TopoDS::Edge(sh));
            double fp = curve.FirstParameter();
            double lp = curve.LastParameter();
            GProp_GProps props;
            BRepGProp::LinearProperties(TopoDS::Edge(sh), props);
            double l = props.Mass();
            // Create points with 10 units distance, but at least one at the beginning and end of the edge
            int steps;
            if (l >= 30) //OvG: Increase 10 units distance proportionately to l for larger objects.
            {
                *scale = this->calcDrawScaleFactor(l); //OvG: setup draw scale for constraint
                steps = (int)round(l / (10*( *scale)));
                steps = steps<3?3:steps;
            }
            else if (l >= 20)
            {
                steps = (int)round(l / 10);
                *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint
            }
            else
            {
                steps = 1;
                *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint
            }

            steps = steps>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:steps; //OvG: Place upper limit on number of steps
            double step = (lp - fp) / steps;
            for (int i = 0; i < steps + 1; i++) {
                gp_Pnt p = curve.Value(i * step);
                points.push_back(Base::Vector3d(p.X(), p.Y(), p.Z()));
                normals.push_back(NormalDirection.getValue());
            }
        }
        else if (sh.ShapeType() == TopAbs_FACE) {
            TopoDS_Face face = TopoDS::Face(sh);

            // Surface boundaries
            BRepAdaptor_Surface surface(face);
            double ufp = surface.FirstUParameter();
            double ulp = surface.LastUParameter();
            double vfp = surface.FirstVParameter();
            double vlp = surface.LastVParameter();
            double l;
            double lv, lu;

            // Surface normals
            BRepGProp_Face props(face);
            gp_Vec normal;
            gp_Pnt center;

            // Get an estimate for the number of arrows by finding the average length of curves
            Handle(Adaptor3d_HSurface) hsurf;
            hsurf = new BRepAdaptor_HSurface(surface);

            Adaptor3d_IsoCurve isoc(hsurf);
            try {
                isoc.Load(GeomAbs_IsoU, ufp);
                l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion());
            }
            catch (const Standard_Failure&) {
                gp_Pnt p1 = hsurf->Value(ufp, vfp);
                gp_Pnt p2 = hsurf->Value(ufp, vlp);
                l = p1.Distance(p2);
            }

            try {
                isoc.Load(GeomAbs_IsoU, ulp);
                lv = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0;
            }
            catch (const Standard_Failure&) {
                gp_Pnt p1 = hsurf->Value(ulp, vfp);
                gp_Pnt p2 = hsurf->Value(ulp, vlp);
                lv = (l + p1.Distance(p2))/2.0;
            }

            try {
                isoc.Load(GeomAbs_IsoV, vfp);
                l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion());
            }
            catch (const Standard_Failure&) {
                gp_Pnt p1 = hsurf->Value(ufp, vfp);
                gp_Pnt p2 = hsurf->Value(ulp, vfp);
                l = p1.Distance(p2);
            }

            try {
                isoc.Load(GeomAbs_IsoV, vlp);
                lu = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0;
            }
            catch (const Standard_Failure&) {
                gp_Pnt p1 = hsurf->Value(ufp, vlp);
                gp_Pnt p2 = hsurf->Value(ulp, vlp);
                lu = (l + p1.Distance(p2))/2.0;
            }

            int stepsv;
            if (lv >= 30) //OvG: Increase 10 units distance proportionately to lv for larger objects.
            {
                *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint
                stepsv = (int)round(lv / (10*( *scale)));
                stepsv = stepsv<3?3:stepsv;
            }
            else if (lv >= 20.0)
            {
                stepsv = (int)round(lv / 10);
                *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint
            }
            else
            {
                stepsv = 2; // Minimum of three arrows to ensure (as much as possible) that at least one is displayed
                *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint
            }

            stepsv = stepsv>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsv; //OvG: Place upper limit on number of steps
            int stepsu;
            if (lu >= 30) //OvG: Increase 10 units distance proportionately to lu for larger objects.
            {
                *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint
                stepsu = (int)round(lu / (10*( *scale)));
                stepsu = stepsu<3?3:stepsu;
            }
            else if (lu >= 20.0)
            {
                stepsu = (int)round(lu / 10);
                *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint
            }
            else
            {
                stepsu = 2;
                *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint
            }

            stepsu = stepsu>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsu; //OvG: Place upper limit on number of steps
            double stepv = (vlp - vfp) / stepsv;
            double stepu = (ulp - ufp) / stepsu;
            // Create points and normals
            for (int i = 0; i < stepsv + 1; i++) {
                for (int j = 0; j < stepsu + 1; j++) {
                    double v = vfp + i * stepv;
                    double u = ufp + j * stepu;
                    gp_Pnt p = surface.Value(u, v);
                    BRepClass_FaceClassifier classifier(face, p, Precision::Confusion());
                    if (classifier.State() != TopAbs_OUT) {
                        points.push_back(Base::Vector3d(p.X(), p.Y(), p.Z()));
                        props.Normal(u, v,center,normal);
                        normal.Normalize();
                        normals.push_back(Base::Vector3d(normal.X(), normal.Y(), normal.Z()));
                    }
                }
            }
        }
    }

    return true;
}