Ejemplo n.º 1
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);
}
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()));
}
Ejemplo 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;
    }
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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; 
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
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");
      }
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
}
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();
    }
}
Ejemplo n.º 14
0
//----------------------------------------------------------------
// Function: TopoDS_Shape level function to update the core Surface
//           for any movement  or Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCSurface::update_OCC_entity(TopoDS_Face& old_surface,
                                          TopoDS_Shape& new_surface,
                                          BRepBuilderAPI_MakeShape *op,
                                          TopoDS_Vertex* removed_vertex,
                                          LocOpe_SplitShape* sp) 
{
  //set the Wires
  TopTools_IndexedMapOfShape M, M2;
  TopoDS_Shape shape, shape2, shape_edge, shape_vertex;
  TopExp::MapShapes(old_surface, TopAbs_WIRE, M);

  TopTools_ListOfShape shapes;  
  BRepFilletAPI_MakeFillet2d* test_op = NULL;

  for (int ii=1; ii<=M.Extent(); ii++) 
  {
     TopoDS_Wire wire = TopoDS::Wire(M(ii));
     TopTools_ListOfShape shapes;
     if(op)
     {
       test_op = dynamic_cast<BRepFilletAPI_MakeFillet2d*>(op);
       if(!test_op)
         shapes.Assign(op->Modified(wire));
       if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(wire));
       if(!new_surface.IsNull())
         TopExp::MapShapes(new_surface,TopAbs_WIRE, M2);
     }
     else if(sp)
       shapes.Assign(sp->DescendantShapes(wire));

     if (shapes.Extent() == 1)
     {
       shape = shapes.First();
       if(M2.Extent() == 1)
       {
         shape2 = TopoDS::Wire(M2(1));
         if(!shape.IsSame(shape2))
           shape = shape2;
       }
       else if(M2.Extent() > 1)
         shape.Nullify();
     }
     else if(shapes.Extent() > 1)
       shape.Nullify();
     else if(op->IsDeleted(wire) || shapes.Extent() == 0)
     {
       TopTools_IndexedMapOfShape M_new;
       TopExp::MapShapes(new_surface, TopAbs_WIRE, M_new);
       if (M_new.Extent()== 1)
         shape = M_new(1);
       else
         shape.Nullify();
     }
     else
     {
       shape = wire;
       continue;
     }

     //set curves
     BRepTools_WireExplorer Ex;
      
     for(Ex.Init(wire); Ex.More();Ex.Next())
     {
       TopoDS_Edge edge = Ex.Current();
       if(op && !test_op)
       {
         shapes.Assign(op->Modified(edge));
         if(shapes.Extent() == 0)
           shapes.Assign(op->Generated(edge));
       }
         
       else if(sp)
         shapes.Assign(sp->DescendantShapes(edge));

       if (shapes.Extent() == 1)
       {
        //in fillet creating mothod, one edge could generated a face, so check
        //it here.
         TopAbs_ShapeEnum type = shapes.First().TShape()->ShapeType(); 
         if(type != TopAbs_EDGE)
           shape_edge.Nullify();
         else
           shape_edge = shapes.First();
       }
       else if (shapes.Extent() > 1)
       {
         //update all attributes first.
         TopTools_ListIteratorOfListOfShape it;
         it.Initialize(shapes);
         for(; it.More(); it.Next())
         {
           shape_edge = it.Value();
           OCCQueryEngine::instance()->copy_attributes(edge, shape_edge);
         }
         shape_edge.Nullify();
       }
       else if (op->IsDeleted(edge))
         shape_edge.Nullify(); 
       else if (test_op)
       {
         if(!test_op->IsModified(edge))
           shape_edge = edge;
         else
           shape_edge = (test_op->Modified(edge)).First();
       } 
       else
         shape_edge = edge;

       //update vertex
       TopoDS_Vertex vertex = Ex.CurrentVertex();
       shapes.Clear();
       if(test_op)
         assert(removed_vertex != NULL);

       if(op && ! test_op )
         shapes.Assign(op->Modified(vertex));
       else if(sp)
         shapes.Assign(sp->DescendantShapes(vertex));

       if (shapes.Extent() == 1)
         shape_vertex = shapes.First();

       else if(shapes.Extent() > 1)
       {
         //update all attributes first.
         TopTools_ListIteratorOfListOfShape it;
         it.Initialize(shapes);
         for(; it.More(); it.Next())
         {
           shape_vertex = it.Value();
           OCCQueryEngine::instance()->copy_attributes(vertex, shape_vertex);
         }
         shape_vertex.Nullify() ;
       }
       else if(op->IsDeleted(vertex) || (test_op && vertex.IsSame( *removed_vertex)))
         shape_vertex.Nullify() ;
         
       else
         shape_vertex = vertex;
      
       if(!vertex.IsSame(shape_vertex) )
         OCCQueryEngine::instance()->update_OCC_map(vertex, shape_vertex);

       if (!edge.IsSame(shape_edge))
         OCCQueryEngine::instance()->update_OCC_map(edge, shape_edge);
     }
     if (!wire.IsSame(shape))
       OCCQueryEngine::instance()->update_OCC_map(wire, shape);
  }
  double dTOL = OCCQueryEngine::instance()->get_sme_resabs_tolerance();
  if (!old_surface.IsSame(new_surface))
  {
    TopAbs_ShapeEnum shapetype =  TopAbs_SHAPE;
    if(!new_surface.IsNull())
      shapetype = new_surface.TShape()->ShapeType();  
    if(shapetype == TopAbs_FACE || new_surface.IsNull())
      OCCQueryEngine::instance()->update_OCC_map(old_surface, new_surface);
    else 
    {
      TopTools_IndexedMapOfShape M;
      TopExp::MapShapes(new_surface, TopAbs_FACE, M);   
      TopoDS_Shape new_shape;
      if(M.Extent() == 1)
        new_shape = M(1);
      else if(M.Extent() > 1)
      {
        for(int i = 1; i <= M.Extent(); i++)
        {
          GProp_GProps myProps;
          BRepGProp::SurfaceProperties(old_surface, myProps);
          double orig_mass = myProps.Mass();
          gp_Pnt orig_pnt = myProps.CentreOfMass();
          BRepGProp::SurfaceProperties(M(i), myProps);
          double after_mass = myProps.Mass();
          gp_Pnt after_pnt = myProps.CentreOfMass();
          if(fabs(-after_mass + orig_mass) <= dTOL && 
             orig_pnt.IsEqual(after_pnt, dTOL))
          {
            new_shape = M(i);
            break;
          }
        }
      }
      OCCQueryEngine::instance()->update_OCC_map(old_surface, new_shape);
    }
  }
  return CUBIT_SUCCESS;
}
Ejemplo n.º 15
0
const std::list<gp_Trsf> MultiTransform::getTransformations(const std::vector<App::DocumentObject*> originals)
{
    std::vector<App::DocumentObject*> transFeatures = Transformations.getValues();

    // 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::FeatureAddSub::getClassTypeId())) {
        PartDesign::FeatureAddSub* addFeature = static_cast<PartDesign::FeatureAddSub*>(originalFeature);
        if(addFeature->getAddSubType() == FeatureAddSub::Additive)
            original = addFeature->AddSubShape.getShape()._Shape;
        else 
            original = addFeature->AddSubShape.getShape()._Shape;
    }

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

    std::list<gp_Trsf> result;
    std::list<gp_Pnt> cogs;
    std::vector<App::DocumentObject*>::const_iterator f;

    for (f = transFeatures.begin(); f != transFeatures.end(); ++f) {
        if (!((*f)->getTypeId().isDerivedFrom(PartDesign::Transformed::getClassTypeId())))
            throw Base::Exception("Transformation features must be subclasses of Transformed");
        PartDesign::Transformed* transFeature = static_cast<PartDesign::Transformed*>(*f);
        std::list<gp_Trsf> newTransformations = transFeature->getTransformations(originals);

        if (result.empty()) {
            // First transformation Feature
            result = newTransformations;
            for (std::list<gp_Trsf>::const_iterator nt = newTransformations.begin(); nt != newTransformations.end(); ++nt) {
                cogs.push_back(cog.Transformed(*nt));
            }
        } else {
            // Retain a copy of the first set of transformations for iterator ot
            // We can't iterate through result if we are also adding elements with push_back()!
            std::list<gp_Trsf> oldTransformations;
            result.swap(oldTransformations); // empty result to receive new transformations
            std::list<gp_Pnt> oldCogs;
            cogs.swap(oldCogs); // empty cogs to receive new cogs

            if ((*f)->getTypeId() == PartDesign::Scaled::getClassTypeId()) {
                // Diagonal method
                // Multiply every element in the old transformations' slices with the corresponding
                // element in the newTransformations. Example:
                // a11 a12 a13 a14          b1    a11*b1 a12*b1 a13*b1 a14*b1
                // a21 a22 a23 a24   diag   b2  = a21*b2 a22*b2 a23*b2 a24*b1
                // a31 a23 a33 a34          b3    a31*b3 a23*b3 a33*b3 a34*b1
                // In other words, the length of the result vector is equal to the length of the
                // oldTransformations vector

                if (oldTransformations.size() % newTransformations.size() != 0)
                    throw Base::Exception("Number of occurrences must be a divisor of previous number of occurrences");

                unsigned sliceLength = oldTransformations.size() / newTransformations.size();
                std::list<gp_Trsf>::const_iterator ot = oldTransformations.begin();
                std::list<gp_Pnt>::const_iterator oc = oldCogs.begin();

                for (std::list<gp_Trsf>::const_iterator nt = newTransformations.begin(); nt != newTransformations.end(); ++nt) {
                    for (unsigned s = 0; s < sliceLength; s++) {
                        gp_Trsf trans;
                        double factor = nt->ScaleFactor(); // extract scale factor

                        if (factor > Precision::Confusion()) {
                            trans.SetScale(*oc, factor); // recreate the scaled transformation to use the correct COG
                            trans = trans * (*ot);
                            cogs.push_back(*oc); // Scaling does not affect the COG
                        } else {
                            trans = (*nt) * (*ot);
                            cogs.push_back(oc->Transformed(*nt));
                        }
                        result.push_back(trans);
                        ++ot;
                        ++oc;
                    }
                }
            } else {
                // Multiplication method: Combine the new transformations with the old ones.
                // All old transformations are multiplied with all new ones, so that the length of the
                // result vector is the length of the old and new transformations multiplied.
                // a11 a12         b1    a11*b1 a12*b1 a11*b2 a12*b2 a11*b3 a12*b3
                // a21 a22   mul   b2  = a21*b1 a22*b1 a21*b2 a22*b2 a21*b3 a22*b3
                //                 b3
                for (std::list<gp_Trsf>::const_iterator nt = newTransformations.begin(); nt != newTransformations.end(); ++nt) {
                    std::list<gp_Pnt>::const_iterator oc = oldCogs.begin();

                    for (std::list<gp_Trsf>::const_iterator ot = oldTransformations.begin(); ot != oldTransformations.end(); ++ot) {
                        result.push_back((*nt) * (*ot));
                        cogs.push_back(oc->Transformed(*nt));
                        ++oc;
                    }
                }
            }
            // What about the Additive method: Take the last (set of) transformations and use them as
            // "originals" for the next transformationFeature, so that something similar to a sweep
            // for transformations could be put together?
        }
    }

    return result;
}
Ejemplo n.º 16
0
//=======================================================================
//function : SortShapes
//purpose  :
//=======================================================================
void GEOMUtils::SortShapes (TopTools_ListOfShape& SL,
                            const Standard_Boolean isOldSorting)
{
#ifdef STD_SORT_ALGO
  std::vector<TopoDS_Shape> aShapesVec;
  aShapesVec.reserve(SL.Extent());

  TopTools_ListIteratorOfListOfShape it (SL);
  for (; it.More(); it.Next()) {
    aShapesVec.push_back(it.Value());
  }
  SL.Clear();

  CompareShapes shComp (isOldSorting);
  std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
  //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);

  std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
  for (; anIter != aShapesVec.end(); ++anIter) {
    SL.Append(*anIter);
  }
#else
  // old implementation
  Standard_Integer MaxShapes = SL.Extent();
  TopTools_Array1OfShape  aShapes (1,MaxShapes);
  TColStd_Array1OfInteger OrderInd(1,MaxShapes);
  TColStd_Array1OfReal    MidXYZ  (1,MaxShapes); //X,Y,Z;
  TColStd_Array1OfReal    Length  (1,MaxShapes); //X,Y,Z;

  // Computing of CentreOfMass
  Standard_Integer Index;
  GProp_GProps GPr;
  gp_Pnt GPoint;
  TopTools_ListIteratorOfListOfShape it(SL);
  for (Index=1;  it.More();  Index++)
  {
    TopoDS_Shape S = it.Value();
    SL.Remove( it ); // == it.Next()
    aShapes(Index) = S;
    OrderInd.SetValue (Index, Index);
    if (S.ShapeType() == TopAbs_VERTEX) {
      GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
      Length.SetValue( Index, (Standard_Real) S.Orientation());
    }
    else {
      // 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();
      Length.SetValue(Index, GPr.Mass());
    }
    MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
    //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
  }

  // Sorting
  Standard_Integer aTemp;
  Standard_Boolean exchange, Sort = Standard_True;
  Standard_Real    tol = Precision::Confusion();
  while (Sort)
  {
    Sort = Standard_False;
    for (Index=1; Index < MaxShapes; Index++)
    {
      exchange = Standard_False;
      Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
      Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
      if ( dMidXYZ >= tol ) {
//         cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
//              << " d: " << dMidXYZ << endl;
        exchange = Standard_True;
      }
      else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
//         cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
//              << " d: " << dLength << endl;
        exchange = Standard_True;
      }
      else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
                aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
        // PAL17233
        // equal values possible on shapes such as two halves of a sphere and
        // a membrane inside the sphere
        Bnd_Box box1,box2;
        BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
        if ( box1.IsVoid() ) continue;
        BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
        Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
        if ( dSquareExtent >= tol ) {
//           cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
          exchange = Standard_True;
        }
        else if ( Abs(dSquareExtent) < tol ) {
          Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
          box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
          val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
          box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
          val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
          //exchange = val1 > val2;
          if ((val1 - val2) >= tol) {
            exchange = Standard_True;
          }
          //cout << "box: " << val1<<" > "<<val2 << endl;
        }
      }

      if (exchange)
      {
//         cout << "exchange " << Index << " & " << Index+1 << endl;
        aTemp = OrderInd(Index);
        OrderInd(Index) = OrderInd(Index+1);
        OrderInd(Index+1) = aTemp;
        Sort = Standard_True;
      }
    }
  }

  for (Index=1; Index <= MaxShapes; Index++)
    SL.Append( aShapes( OrderInd(Index) ));
#endif
}
Ejemplo n.º 17
0
gp_Pnt GetCOG(TopoDS_Shape shape)
{
     GProp_GProps System;                     
	 BRepGProp::SurfaceProperties (shape, System);
     return System.CentreOfMass();     
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
//----------------------------------------------------------------
// Function: TopoDS_Shape level function to update the core Body
//           for any Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCBody::update_OCC_entity(TopoDS_Shape& old_shape,
                                       TopoDS_Shape& new_shape,
                                       BRepBuilderAPI_MakeShape *op,
                                       LocOpe_SplitShape* sp)
{
  //set the Shells
  TopTools_IndexedMapOfShape M;
  TopExp::MapShapes(old_shape, TopAbs_SOLID, M);
  TopTools_IndexedMapOfShape M_new;
  TopExp::MapShapes(new_shape, TopAbs_SOLID, M_new);
  TopTools_ListOfShape shapes;
  TopoDS_Shape shape;

  CubitBoolean updated = CUBIT_FALSE;	
  if(!old_shape.IsNull() && old_shape.ShapeType() == TopAbs_COMPOUND && 
     !new_shape.IsNull() && new_shape.ShapeType() == TopAbs_COMPOUND &&
     !old_shape.IsSame(new_shape))
  {
    //By updating underling solids, shells etc., the old_shape will get changed.
    //trying to make sure the the number of each entity in the old and new 
    //shapes are the same, which means that nothing is delete, that we can 
    //update the map here. Otherwise, when deleting solids, it'll delete the
    //the old body and create new body. This is Ok for general boolean operation    //except imprint when booleans are called, usually the original body are
    // supposed to be kept. 
    updated = CUBIT_TRUE;
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  }
 
  DLIList<int> new_solid_nums;
  DLIList<int> unfound_nums;
  for(int ii=1; ii<=M.Extent(); ii++)
  {
    TopoDS_Solid solid = TopoDS::Solid(M(ii));

    TopTools_ListOfShape shapes;
    if(op)
    {
      shapes.Assign(op->Modified(solid));
      if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(solid));
    }
    else if(sp)
      shapes.Assign(sp->DescendantShapes(solid));

    if (shapes.Extent() == 1)
      shape = shapes.First();

    else if(shapes.Extent() > 1)
    {
      //update all attributes first.
      TopTools_ListIteratorOfListOfShape it;
      it.Initialize(shapes);
      for(; it.More(); it.Next())
      {
        shape = it.Value();
        OCCQueryEngine::instance()->copy_attributes(solid, shape);
      } 
      shape = shapes.First();
    }

    else if(op->IsDeleted(solid))
    {
       if (M_new.Extent()== 1 && ii == 1)
         shape = M_new(1);
       else if(M_new.Extent()== 1 && ii > 1)
         shape.Nullify();
       else if(M_new.Extent() > 1)
       {
         GProp_GProps myProps;
         BRepGProp::VolumeProperties(solid, myProps);
         double bf_mass = myProps.Mass();
         gp_Pnt old_center = myProps.CentreOfMass();
         CubitBoolean found = CUBIT_FALSE;
         for(int l = 1; l <= M_new.Extent(); l++)
         {
           BRepGProp::VolumeProperties(M_new(l), myProps);
           double af_mass = myProps.Mass();
           double dTol = OCCQueryEngine::instance()->get_sme_resabs_tolerance();
           if(fabs(bf_mass-af_mass) < dTol) //unchanged
           {
             gp_Pnt  new_center = myProps.CentreOfMass(); 
             if(new_center.IsEqual(old_center, dTol))
             {
               found = CUBIT_TRUE;
               shape = M_new(l);
               new_solid_nums.append(l);
               break;
             }
           }
         }
         if(!found)
         {
           unfound_nums.append(ii); 
           continue;
         }
       }
       else
         shape.Nullify();
    }
    else
    {
       shape = solid;
       continue;
    }

    if(shapes.Extent() > 0 || (op && op->IsDeleted(solid)))
      OCCLump::update_OCC_entity(solid, shape, op, sp);
  }

  if( unfound_nums.size() == 1 )
  {
    TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get()));
    for(int kk = 1; kk <= M_new.Extent(); kk++)
    {
      if(!new_solid_nums.move_to(kk))
      {
        shape = M_new(kk);
        break;
      } 
    }
    OCCLump::update_OCC_entity(solid, shape, op, sp);
  }
  else if(unfound_nums.size() > 1)
  {
    shape.Nullify();
    for(int kk = 1; kk <=unfound_nums.size(); kk++)
    {
       TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get_and_step()));
       OCCLump::update_OCC_entity(solid, shape, op, sp);
    }
  } 
  if(!old_shape.IsSame(new_shape) && !updated)
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  return CUBIT_SUCCESS;
}