Base::BoundBox3d PropertyPointKernel::getBoundingBox() const
{
    Base::BoundBox3d box;
    for (PointKernel::const_iterator it = _cPoints->begin(); it != _cPoints->end(); ++it)
        box.Add(*it);
    return box;
}
示例#2
0
    void onSelectionChanged(const Gui::SelectionChanges& msg)
    {
        Base::BoundBox3d bbox;
        unsigned long countPoints=0, countFacets=0;
        std::vector<Mesh::Feature*> mesh = Gui::Selection().getObjectsOfType<Mesh::Feature>();
        for (std::vector<Mesh::Feature*>::iterator it = mesh.begin(); it != mesh.end(); ++it) {
            countPoints += (*it)->Mesh.getValue().countPoints();
            countFacets += (*it)->Mesh.getValue().countFacets();
            bbox.Add((*it)->Mesh.getBoundingBox());
        }

        if (countPoints > 0) {
            numPoints->setText(QString::number(countPoints));
            numFacets->setText(QString::number(countFacets));
            numMin->setText(QString::fromAscii("X: %1\tY: %2\tZ: %3")
                .arg(bbox.MinX).arg(bbox.MinX).arg(bbox.MinX));
            numMax->setText(QString::fromAscii("X: %1\tY: %2\tZ: %3")
                .arg(bbox.MaxX).arg(bbox.MaxX).arg(bbox.MaxX));
        }
        else {
            numPoints->setText(QString::fromAscii(""));
            numFacets->setText(QString::fromAscii(""));
            numMin->setText(QString::fromAscii(""));
            numMax->setText(QString::fromAscii(""));
        }
    }
示例#3
0
Base::Vector3d TransformStrategy::getRotationCenter() const
{
    // get the global bounding box of all selected objects and use its center as
    // rotation center
    std::set<App::DocumentObject*> objects = transformObjects();
    if (!objects.empty()) {
        Base::BoundBox3d bbox;
        bool first=true;
        for (std::set<App::DocumentObject*>::const_iterator it=objects.begin();it!=objects.end();++it) {
            std::map<std::string,App::Property*> props;
            (*it)->getPropertyMap(props);
            // search for a data property
            std::map<std::string,App::Property*>::iterator jt;
            jt = std::find_if(props.begin(), props.end(), find_geometry_data());
            if (jt != props.end()) {
                if (first)
                    bbox = (static_cast<App::PropertyGeometry*>(jt->second)->getBoundingBox());
                else
                    bbox.Add(static_cast<App::PropertyGeometry*>(jt->second)->getBoundingBox());
                first = false;
            }
        }

        return Base::Vector3d((bbox.MinX+bbox.MaxX)/2,
                              (bbox.MinY+bbox.MaxY)/2,
                              (bbox.MinZ+bbox.MaxZ)/2);
    }

    return Base::Vector3d();
}
Base::BoundBox3d PointKernel::getBoundBox(void)const
{
    Base::BoundBox3d bnd;
    for (const_point_iterator it = begin(); it != end(); ++it)
        bnd.Add(*it);
    return bnd;
}
示例#5
0
Base::BoundBox3d DrawProjGroup::getBoundingBox() const
{
    Base::BoundBox3d bbox;

    std::vector<App::DocumentObject*> views = Views.getValues();
    TechDraw::DrawProjGroupItem *anchorView = dynamic_cast<TechDraw::DrawProjGroupItem *>(Anchor.getValue());
    for (std::vector<App::DocumentObject*>::const_iterator it = views.begin(); it != views.end(); ++it) {
         if ((*it)->getTypeId().isDerivedFrom(DrawViewPart::getClassTypeId())) {
            DrawViewPart *part = static_cast<DrawViewPart *>(*it);
            Base::BoundBox3d  bb = part->getBoundingBox();

            bb.ScaleX(1. / part->Scale.getValue());
            bb.ScaleY(1. / part->Scale.getValue());

            // X and Y of dependant views are relative to the anchorView
            if (part != anchorView) {
                bb.MoveX(part->X.getValue());
                bb.MoveY(part->Y.getValue());
            }

            bbox.Add(bb);
        }
    }
    // This /should/ leave the centre of the bounding box at (0,0) except when
    // we're in the process of updating the anchor view's position (eg called
    // by moveToCentre())
    if (anchorView) { //TODO: It looks like we might be getting called before an anchor view is set - weird...
        bbox.MoveX(anchorView->X.getValue());
        bbox.MoveY(anchorView->Y.getValue());
    }
    return bbox;
}
示例#6
0
Base::BoundBox3d GeometryObject::boundingBoxOfAoe(const Ellipse *aoe,
        double start,
        double end, bool cw) const
{
    // Using the ellipse form:
    // (xc, yc) = centre of ellipse
    // phi = angle of ellipse major axis off X axis
    // a, b = half of major, minor axes
    //
    // x(theta) = xc + a*cos(theta)*cos(phi) - b*sin(theta)*sin(phi)
    // y(theta) = yc + a*cos(theta)*sin(phi) + b*sin(theta)*cos(phi)

    double a (aoe->major / 2.0),
           b (aoe->minor / 2.0),
           phi (aoe->angle),
           xc (aoe->center.fX),
           yc (aoe->center.fY);

    if (a == 0 || b == 0) {
        // Degenerate case - TODO: handle as line instead of throwing
        throw Base::Exception("Ellipse with invalid major axis in GeometryObject::boundingBoxOfAoe()");
    }

    // Calculate points of interest for the bounding box.  These are points
    // where d(x)/d(theta) and d(y)/d(theta) = 0 (where the x and y extremes
    // of the ellipse would be if it were complete), and arc endpoints.
    double testAngles[6] = { atan(tan(phi) * (-b / a)),
                             testAngles[0] + M_PI
                           };
    if (tan(phi) == 0) {
        testAngles[2] = M_PI / 2.0;
        testAngles[3] = 3.0 * M_PI / 2.0;
    } else {
        testAngles[2] = atan((1.0 / tan(phi)) * (b / a));
        testAngles[3] = testAngles[2] + M_PI;
    }
    testAngles[4] = start;
    testAngles[5] = end;

    // Add extremes to bounding box, if they are within the arc
    Base::BoundBox3d bb;
    for (int ai(0); ai < 6; ++ai) {
        double theta(testAngles[ai]);
        if (isWithinArc(theta, start, end, cw) ) {
            bb.Add( Base::Vector3d(xc + a*cos(theta)*cos(phi) - b*sin(theta)*sin(phi),
                                   yc + a*cos(theta)*sin(phi) - b*sin(theta)*cos(phi),
                                   0) );
        }
    }

    return bb;
}
示例#7
0
void CmdPartCrossSections::activated(int iMsg)
{
    Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
    if (!dlg) {
        std::vector<App::DocumentObject*> obj = Gui::Selection().getObjectsOfType
            (Part::Feature::getClassTypeId());
        Base::BoundBox3d bbox;
        for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it) {
            bbox.Add(static_cast<Part::Feature*>(*it)->Shape.getBoundingBox());
        }
        dlg = new PartGui::TaskCrossSections(bbox);
    }
    Gui::Control().showDialog(dlg);
}
示例#8
0
PointsGrid::PointsGrid (const PointKernel &rclM, double fGridLen)
: _pclPoints(&rclM),
  _ulCtElements(0),
  _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0),
  _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
  _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
{
  Base::BoundBox3d clBBPts;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPts.Add(*it);
  Rebuild(std::max<unsigned long>((unsigned long)(clBBPts.LengthX() / fGridLen), 1),
          std::max<unsigned long>((unsigned long)(clBBPts.LengthY() / fGridLen), 1),
          std::max<unsigned long>((unsigned long)(clBBPts.LengthZ() / fGridLen), 1));
}
示例#9
0
void PointsGrid::InitGrid (void)
{
  assert(_pclPoints != NULL);

  unsigned long i, j;

  // Grid Laengen berechnen wenn nicht initialisiert
  //
  if ((_ulCtGridsX == 0) || (_ulCtGridsY == 0) || (_ulCtGridsZ == 0))
    CalculateGridLength(POINTS_CT_GRID, POINTS_MAX_GRIDS);

  // Grid Laengen und Offset bestimmen
  //
  {
  Base::BoundBox3d clBBPts;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPts.Add(*it);

  double fLengthX = clBBPts.LengthX(); 
  double fLengthY = clBBPts.LengthY();
  double fLengthZ = clBBPts.LengthZ();

  {
    // Offset fGridLen/2
    //
    _fGridLenX = (1.0f + fLengthX) / double(_ulCtGridsX);
    _fMinX = clBBPts.MinX - 0.5f;
  }

  {
    _fGridLenY = (1.0f + fLengthY) / double(_ulCtGridsY);
    _fMinY = clBBPts.MinY - 0.5f;
  }

  {
    _fGridLenZ = (1.0f + fLengthZ) / double(_ulCtGridsZ);
    _fMinZ = clBBPts.MinZ - 0.5f;
  }
  }

  // Daten-Struktur anlegen
  _aulGrid.clear();
  _aulGrid.resize(_ulCtGridsX);
  for (i = 0; i < _ulCtGridsX; i++)
  {
    _aulGrid[i].resize(_ulCtGridsY);
    for (j = 0; j < _ulCtGridsY; j++)
      _aulGrid[i][j].resize(_ulCtGridsZ);
  }
}
void Tessellation::findShapes()
{
    App::Document* activeDoc = App::GetApplication().getActiveDocument();
    if (!activeDoc) return;
    Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
    if (!activeGui) return;

    this->document = QString::fromAscii(activeDoc->getName());
    std::vector<Part::Feature*> objs = activeDoc->getObjectsOfType<Part::Feature>();

    double edgeLen = 0;
    bool foundSelection = false;
    for (std::vector<Part::Feature*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
        const TopoDS_Shape& shape = (*it)->Shape.getValue();
        if (shape.IsNull()) continue;
        bool hasfaces = false;
        TopExp_Explorer xp(shape,TopAbs_FACE);
        while (xp.More()) {
            hasfaces = true;
            break;
        }

        if (hasfaces) {
            Base::BoundBox3d bbox = (*it)->Shape.getBoundingBox();
            edgeLen = std::max<double>(edgeLen, bbox.LengthX());
            edgeLen = std::max<double>(edgeLen, bbox.LengthY());
            edgeLen = std::max<double>(edgeLen, bbox.LengthZ());
            QString label = QString::fromUtf8((*it)->Label.getValue());
            QString name = QString::fromAscii((*it)->getNameInDocument());
            
            QTreeWidgetItem* child = new QTreeWidgetItem();
            child->setText(0, label);
            child->setToolTip(0, label);
            child->setData(0, Qt::UserRole, name);
            Gui::ViewProvider* vp = activeGui->getViewProvider(*it);
            if (vp) child->setIcon(0, vp->getIcon());
            ui->treeWidget->addTopLevelItem(child);
            if (Gui::Selection().isSelected(*it)) {
                child->setSelected(true);
                foundSelection = true;
            }
        }
    }

    ui->spinMaximumEdgeLength->setValue(edgeLen/10);
    if (foundSelection)
        ui->treeWidget->hide();
}
void ViewProvider2DObject::updateData(const App::Property* prop)
{
    ViewProviderPart::updateData(prop);

    if (prop->getTypeId() == Part::PropertyPartShape::getClassTypeId()) {
        Base::BoundBox3d bbox = static_cast<const Part::PropertyPartShape*>(prop)->getBoundingBox();
        if (!bbox.IsValid()) return;
        GridRoot->removeAllChildren();
        Base::Placement place = static_cast<const Part::PropertyPartShape*>(prop)->getComplexData()->getPlacement();
        place.invert();
        Base::ViewProjMatrix proj(place.toMatrix());
        Base::BoundBox2D bbox2d = bbox.ProjectBox(&proj);
        this->MinX = bbox2d.fMinX;
        this->MaxX = bbox2d.fMaxX;
        this->MinY = bbox2d.fMinY;
        this->MaxY = bbox2d.fMaxY;
        if (ShowGrid.getValue()) {
            createGrid();
        }
    }
}
示例#12
0
Base::BoundBox3d PointKernel::getBoundBox(void)const
{
    Base::BoundBox3d bnd;

    //FIXME: VS 2015 or later causes a linker error
#if defined _WIN32 
    // Thread-local bounding boxes
    Concurrency::combinable<Base::BoundBox3d> bbs;
    // Cannot use a const_point_iterator here as it is *not* a proper iterator (fails the for_each template)
    Concurrency::parallel_for_each(_Points.begin(), _Points.end(), [this, &bbs](const value_type& value) {
        Base::Vector3d vertd(value.x, value.y, value.z);
        bbs.local().Add(this->_Mtrx * vertd);
    });
    // Combine each thread-local bounding box in the final bounding box
    bbs.combine_each([&bnd](const Base::BoundBox3d& lbb) {
        bnd.Add(lbb);
    });
#else
    for (const_point_iterator it = begin(); it != end(); ++it)
        bnd.Add(*it);
#endif
    return bnd;
}
示例#13
0
Base::BoundBox3d GeometryObject::calcBoundingBox() const
{
    Base::BoundBox3d bbox;

    // First calculate bounding box based on vertices
    for(std::vector<Vertex *>::const_iterator it( vertexGeom.begin() );
            it != vertexGeom.end(); ++it) {
        bbox.Add( Base::Vector3d((*it)->pnt.fX, (*it)->pnt.fY, 0.) );
    }

    // Now, consider geometry where vertices don't define bounding box eg circles
    for (std::vector<BaseGeom *>::const_iterator it( edgeGeom.begin() );
            it != edgeGeom.end(); ++it) {
        switch ((*it)->geomType) {
        case CIRCLE: {
            Circle *c = static_cast<Circle *>(*it);
            bbox.Add( Base::BoundBox3d(-c->radius + c->center.fX,
                                       -c->radius + c->center.fY,
                                       0,
                                       c->radius + c->center.fX,
                                       c->radius + c->center.fY,
                                       0) );
        }
        break;

        case ARCOFCIRCLE: {
            AOC *arc = static_cast<AOC *>(*it);

            // Endpoints of arc
            bbox.Add( Base::Vector3d(arc->radius * cos(arc->startAngle),
                                     arc->radius * sin(arc->startAngle),
                                     0.0) );
            bbox.Add( Base::Vector3d(arc->radius * cos(arc->endAngle),
                                     arc->radius * sin(arc->endAngle),
                                     0.0) );

            // Extreme X and Y values if they're within the arc
            for (double theta = 0.0; theta < 6.5; theta += M_PI / 2.0) {
                if (isWithinArc(theta, arc->startAngle, arc->endAngle, arc->cw)) {
                    bbox.Add( Base::Vector3d(arc->radius * cos(theta),
                                             arc->radius * sin(theta),
                                             0.0) );
                }
            }
        }
        break;

        case ELLIPSE: {
            bbox.Add( boundingBoxOfAoe(static_cast<Ellipse *>(*it)) );
        }
        break;

        case ARCOFELLIPSE: {
            AOE *aoe = static_cast<AOE *>(*it);
            double start = aoe->startAngle,
                   end = aoe->endAngle;
            bool cw = aoe->cw;
            bbox.Add( boundingBoxOfAoe(static_cast<Ellipse *>(*it), start, end, cw) );
        }
        break;

        case BSPLINE: {
            bbox.Add( boundingBoxOfBspline(static_cast<BSpline *>(*it)) );
        }
        break;

        case GENERIC: {
            // this case ends up just drawing line segments between points
            Generic *gen = static_cast<Generic *>(*it);
            for (std::vector<Base::Vector2D>::const_iterator segIt = gen->points.begin();
                    segIt != gen->points.end(); ++segIt) {
                bbox.Add( Base::Vector3d(segIt->fX, segIt->fY, 0) );
            }
        }
        break;

        default:
            throw Base::Exception("Unknown geomType in GeometryObject::calcBoundingBox()");
        }
    }
    return bbox;
}
示例#14
0
void PointsGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids)
{
  // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen
  // pro Grid sollen ca. 10 (?!?!) Facets liegen
  // bzw. max Grids sollten 10000 nicht ueberschreiten
  Base::BoundBox3d clBBPtsEnlarged;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPtsEnlarged.Add(*it);
  double fVolElem;

  if (_ulCtElements > (ulMaxGrids * ulCtGrid))
    fVolElem = (clBBPtsEnlarged.LengthX() * clBBPtsEnlarged.LengthY() * clBBPtsEnlarged.LengthZ()) / float(ulMaxGrids * ulCtGrid);
  else
    fVolElem = (clBBPtsEnlarged.LengthX() * clBBPtsEnlarged.LengthY() * clBBPtsEnlarged.LengthZ()) / float(_ulCtElements);

  double fVol     = fVolElem * float(ulCtGrid);
  double fGridLen = float(pow((float)fVol,(float) 1.0f / 3.0f));

  _ulCtGridsX = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthX() / fGridLen), 1);
  _ulCtGridsY = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthY() / fGridLen), 1);
  _ulCtGridsZ = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthZ() / fGridLen), 1);
}
示例#15
0
void PointsGrid::CalculateGridLength (int iCtGridPerAxis)
{
  if (iCtGridPerAxis<=0)
  {
    CalculateGridLength(POINTS_CT_GRID, POINTS_MAX_GRIDS);
    return;
  }

  // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen
  // pro Grid sollen ca. 10 (?!?!) Facets liegen
  // bzw. max Grids sollten 10000 nicht ueberschreiten
  Base::BoundBox3d clBBPts;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPts.Add(*it);

  double fLenghtX = clBBPts.LengthX();
  double fLenghtY = clBBPts.LengthY();
  double fLenghtZ = clBBPts.LengthZ();

  double fLenghtD = clBBPts.CalcDiagonalLength();

  double fLengthTol = 0.05f * fLenghtD;

  bool bLenghtXisZero = (fLenghtX <= fLengthTol);
  bool bLenghtYisZero = (fLenghtY <= fLengthTol);
  bool bLenghtZisZero = (fLenghtZ <= fLengthTol);

  int iFlag  = 0;

  int iMaxGrids = 1;

  if (bLenghtXisZero)  
    iFlag += 1; 
  else
    iMaxGrids *= iCtGridPerAxis;

  if (bLenghtYisZero) 
    iFlag += 2;
  else
    iMaxGrids *= iCtGridPerAxis;

  if (bLenghtZisZero)
    iFlag += 4; 
  else
    iMaxGrids *= iCtGridPerAxis;
  
  unsigned long ulGridsFacets =   10;

  double fFactorVolumen = 40.0;
  double fFactorArea    = 10.0;

  switch (iFlag)
  {
  case 0:
    {
      double fVolumen = fLenghtX * fLenghtY * fLenghtZ;

      double fVolumenGrid = (fVolumen * ulGridsFacets) / (fFactorVolumen * _ulCtElements);

      if ((fVolumenGrid * iMaxGrids) < fVolumen)
        fVolumenGrid = fVolumen / (float)iMaxGrids;

      double fLengthGrid = float(pow((float)fVolumenGrid,(float) 1.0f / 3.0f));

      _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
      _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
      _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
      
    } break;
  case 1:
    {
      _ulCtGridsX = 1; // bLenghtXisZero
      
      double fArea = fLenghtY * fLenghtZ;

      double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);

      if ((fAreaGrid * iMaxGrids) < fArea)
        fAreaGrid = fArea / (double)iMaxGrids;

      double fLengthGrid = double(sqrt(fAreaGrid));

      _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
      _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
    } break;
  case 2:
    {
      _ulCtGridsY = 1; // bLenghtYisZero
  
      double fArea = fLenghtX * fLenghtZ;

      double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);

      if ((fAreaGrid * iMaxGrids) < fArea)
        fAreaGrid = fArea / (double)iMaxGrids;

      double fLengthGrid = double(sqrt(fAreaGrid));

      _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
      _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
    } break;
  case 3:
    {
      _ulCtGridsX = 1; // bLenghtXisZero
      _ulCtGridsY = 1; // bLenghtYisZero
      _ulCtGridsZ = iMaxGrids; // bLenghtYisZero
    } break;
  case 4:
    {
      _ulCtGridsZ = 1; // bLenghtZisZero
      
      double fArea = fLenghtX * fLenghtY;

      double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);

      if ((fAreaGrid * iMaxGrids) < fArea)
        fAreaGrid = fArea / (float)iMaxGrids;

      double fLengthGrid = double(sqrt(fAreaGrid));

      _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
      _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
    } break;
  case 5:
    {
      _ulCtGridsX = 1; // bLenghtXisZero
      _ulCtGridsZ = 1; // bLenghtZisZero
      _ulCtGridsY = iMaxGrids; // bLenghtYisZero
    } break;
  case 6:
    {
      _ulCtGridsY = 1; // bLenghtYisZero
      _ulCtGridsZ = 1; // bLenghtZisZero
      _ulCtGridsX = iMaxGrids; // bLenghtYisZero
    } break;
  case 7:
    {
      _ulCtGridsX = iMaxGrids; // bLenghtXisZero
      _ulCtGridsY = iMaxGrids; // bLenghtYisZero
      _ulCtGridsZ = iMaxGrids; // bLenghtZisZero
    } break;
  }
}
void ViewProviderInspection::updateData(const App::Property* prop)
{
    // set to the expected size
    if (prop->getTypeId() == App::PropertyLink::getClassTypeId()) {
        App::GeoFeature* object = static_cast<const App::PropertyLink*>(prop)->getValue<App::GeoFeature*>();
        if (object) {
            float accuracy=0;
            Base::Type meshId  = Base::Type::fromName("Mesh::Feature");
            Base::Type shapeId = Base::Type::fromName("Part::Feature");
            Base::Type pointId = Base::Type::fromName("Points::Feature");
            Base::Type propId  = App::PropertyComplexGeoData::getClassTypeId();

            // set the Distance property to the correct size to sync size of material node with number
            // of vertices/points of the referenced geometry
            const Data::ComplexGeoData* data = 0;
            if (object->getTypeId().isDerivedFrom(meshId)) {
                App::Property* prop = object->getPropertyByName("Mesh");
                if (prop && prop->getTypeId().isDerivedFrom(propId)) {
                    data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
                }
            }
            else if (object->getTypeId().isDerivedFrom(shapeId)) {
                App::Property* prop = object->getPropertyByName("Shape");
                if (prop && prop->getTypeId().isDerivedFrom(propId)) {
                    data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
                    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath
                        ("User parameter:BaseApp/Preferences/Mod/Part");
                    float deviation = hGrp->GetFloat("MeshDeviation",0.2);

                    Base::BoundBox3d bbox = data->getBoundBox();
                    accuracy = (float)((bbox.LengthX() + bbox.LengthY() + bbox.LengthZ())/300.0 * deviation);
                }
            }
            else if (object->getTypeId().isDerivedFrom(pointId)) {
                App::Property* prop = object->getPropertyByName("Points");
                if (prop && prop->getTypeId().isDerivedFrom(propId)) {
                    data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
                }
            }

            if (data) {
                this->pcLinkRoot->removeAllChildren();
                std::vector<Base::Vector3d> points;
                std::vector<Data::ComplexGeoData::Facet> faces;
                data->getFaces(points, faces, accuracy);

                this->pcLinkRoot->addChild(this->pcCoords);
                this->pcCoords->point.setNum(points.size());
                SbVec3f* pts = this->pcCoords->point.startEditing();
                for (size_t i=0; i < points.size(); i++) {
                    const Base::Vector3d& p = points[i];
                    pts[i].setValue((float)p.x,(float)p.y,(float)p.z);
                }
                this->pcCoords->point.finishEditing();

                if (!faces.empty()) {
                    SoIndexedFaceSet* face = new SoIndexedFaceSet();
                    this->pcLinkRoot->addChild(face);
                    face->coordIndex.setNum(4*faces.size());
                    int32_t* indices = face->coordIndex.startEditing();
                    unsigned long j=0;
                    std::vector<Data::ComplexGeoData::Facet>::iterator it;
                    for (it = faces.begin(); it != faces.end(); ++it,j++) {
                        indices[4*j+0] = it->I1;
                        indices[4*j+1] = it->I2;
                        indices[4*j+2] = it->I3;
                        indices[4*j+3] = SO_END_FACE_INDEX;
                    }
                    face->coordIndex.finishEditing();
                }
                else {
                    this->pcLinkRoot->addChild(this->pcPointStyle);
                    this->pcLinkRoot->addChild(new SoPointSet());
                }
            }
        }
    }
    else if (prop->getTypeId() == Inspection::PropertyDistanceList::getClassTypeId()) {
        // force an update of the Inventor data nodes
        if (this->pcObject) {
            App::Property* link = this->pcObject->getPropertyByName("Actual");
            if (link) updateData(link);
        }
        setDistances();
    }
    else if (prop->getTypeId() == App::PropertyFloat::getClassTypeId()) {
        if (strcmp(prop->getName(), "SearchRadius") == 0) {
            float fSearchRadius = ((App::PropertyFloat*)prop)->getValue();
            this->search_radius = fSearchRadius;
            pcColorBar->setRange( -fSearchRadius, fSearchRadius, 4 );
            pcColorBar->Notify(0);
        }
    }
}
App::DocumentObjectExecReturn *DrawViewSection::execute(void)
{
    App::DocumentObject* link = Source.getValue();
    App::DocumentObject* base = BaseView.getValue();
    if (!link || !base)  {
        Base::Console().Log("INFO - DVS::execute - No Source or Link - creation?\n");
        return DrawView::execute();
    }

    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Source object is not a Part object");
    if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()))
        return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object");

    //Base::Console().Message("TRACE - DVS::execute() - %s/%s\n",getNameInDocument(),Label.getValue());

    const Part::TopoShape &partTopo = static_cast<Part::Feature*>(link)->Shape.getShape();

    if (partTopo.getShape().IsNull())
        return new App::DocumentObjectExecReturn("Linked shape object is empty");

    (void) DrawView::execute();          //make sure Scale is up to date

    gp_Pln pln = getSectionPlane();
    gp_Dir gpNormal = pln.Axis().Direction();
    Base::Vector3d orgPnt = SectionOrigin.getValue();

    Base::BoundBox3d bb = partTopo.getBoundBox();
    if(!isReallyInBox(orgPnt, bb)) {
        Base::Console().Warning("DVS: Section Plane doesn't intersect part in %s\n",getNameInDocument());
        Base::Console().Warning("DVS: Using center of bounding box.\n");
        orgPnt = bb.GetCenter();
        SectionOrigin.setValue(orgPnt);
    }

    // Make the extrusion face
    double dMax = bb.CalcDiagonalLength();
    BRepBuilderAPI_MakeFace mkFace(pln, -dMax,dMax,-dMax,dMax);
    TopoDS_Face aProjFace = mkFace.Face();
    if(aProjFace.IsNull())
        return new App::DocumentObjectExecReturn("DrawViewSection - Projected face is NULL");
    gp_Vec extrudeDir = dMax * gp_Vec(gpNormal);
    TopoDS_Shape prism = BRepPrimAPI_MakePrism(aProjFace, extrudeDir, false, true).Shape();

    // We need to copy the shape to not modify the BRepstructure
    BRepBuilderAPI_Copy BuilderCopy(partTopo.getShape());
    TopoDS_Shape myShape = BuilderCopy.Shape();

    BRepAlgoAPI_Cut mkCut(myShape, prism);
    if (!mkCut.IsDone())
        return new App::DocumentObjectExecReturn("Section cut has failed");

    TopoDS_Shape rawShape = mkCut.Shape();
    Bnd_Box testBox;
    BRepBndLib::Add(rawShape, testBox);
    testBox.SetGap(0.0);
    if (testBox.IsVoid()) {                        //prism & input don't intersect.  rawShape is garbage, don't bother.
        Base::Console().Log("INFO - DVS::execute - prism & input don't intersect\n");
        return DrawView::execute();
    }

    gp_Pnt inputCenter;
    try {
        inputCenter = TechDrawGeometry::findCentroid(rawShape,
                                                     Direction.getValue());
        TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape,
                                                    inputCenter,
                                                    Scale.getValue());
        geometryObject = buildGeometryObject(mirroredShape,inputCenter);   //this is original shape after cut by section prism

#if MOD_TECHDRAW_HANDLE_FACES
        extractFaces();
#endif //#if MOD_TECHDRAW_HANDLE_FACES
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e1 = Standard_Failure::Caught();
        Base::Console().Log("LOG - DVS::execute - base shape failed for %s - %s **\n",getNameInDocument(),e1->GetMessageString());
        return new App::DocumentObjectExecReturn(e1->GetMessageString());
    }

    try {
        TopoDS_Compound sectionCompound = findSectionPlaneIntersections(rawShape);
        TopoDS_Shape mirroredSection = TechDrawGeometry::mirrorShape(sectionCompound,
                                                                     inputCenter,
                                                                     Scale.getValue());

        TopoDS_Compound newFaces;
        BRep_Builder builder;
        builder.MakeCompound(newFaces);
        TopExp_Explorer expl(mirroredSection, TopAbs_FACE);
        for (; expl.More(); expl.Next()) {
            const TopoDS_Face& face = TopoDS::Face(expl.Current());
            TopoDS_Face pFace = projectFace(face,
                                            inputCenter,
                                            Direction.getValue());
             if (!pFace.IsNull()) {
                 builder.Add(newFaces,pFace);
             }

        }
        sectionFaces = newFaces;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e2 = Standard_Failure::Caught();
        Base::Console().Log("LOG - DVS::execute - failed building section faces for %s - %s **\n",getNameInDocument(),e2->GetMessageString());
        return new App::DocumentObjectExecReturn(e2->GetMessageString());
    }

    return App::DocumentObject::StdReturn;
}
示例#18
0
bool ViewProviderMirror::setEdit(int ModNum)
{
    if (ModNum == ViewProvider::Default) {
        // get the properties from the mirror feature
        Part::Mirroring* mf = static_cast<Part::Mirroring*>(getObject());
        Base::BoundBox3d bbox = mf->Shape.getBoundingBox();
        float len = (float)bbox.CalcDiagonalLength();
        Base::Vector3d base = mf->Base.getValue();
        Base::Vector3d norm = mf->Normal.getValue();
        Base::Vector3d cent = bbox.GetCenter();
        base = cent.ProjToPlane(base, norm);

        // setup the graph for editing the mirror plane
        SoTransform* trans = new SoTransform;
        SbRotation rot(SbVec3f(0,0,1), SbVec3f(norm.x,norm.y,norm.z));
        trans->rotation.setValue(rot);
        trans->translation.setValue(base.x,base.y,base.z);
        trans->center.setValue(0.0f,0.0f,0.0f);

        SoMaterial* color = new SoMaterial();
        color->diffuseColor.setValue(0,0,1);
        color->transparency.setValue(0.5);
        SoCoordinate3* points = new SoCoordinate3();
        points->point.setNum(4);
        points->point.set1Value(0, -len/2,-len/2,0);
        points->point.set1Value(1,  len/2,-len/2,0);
        points->point.set1Value(2,  len/2, len/2,0);
        points->point.set1Value(3, -len/2, len/2,0);
        SoFaceSet* face = new SoFaceSet();
        pcEditNode->addChild(trans);
        pcEditNode->addChild(color);
        pcEditNode->addChild(points);
        pcEditNode->addChild(face);

        // Now we replace the SoTransform node by a manipulator
        // Note: Even SoCenterballManip inherits from SoTransform
        // we cannot use it directly (in above code) because the
        // translation and center fields are overridden.
        SoSearchAction sa;
        sa.setInterest(SoSearchAction::FIRST);
        sa.setSearchingAll(FALSE);
        sa.setNode(trans);
        sa.apply(pcEditNode);
        SoPath * path = sa.getPath();
        if (path) {
            SoCenterballManip * manip = new SoCenterballManip;
            manip->replaceNode(path);

            SoDragger* dragger = manip->getDragger();
            dragger->addStartCallback(dragStartCallback, this);
            dragger->addFinishCallback(dragFinishCallback, this);
            dragger->addMotionCallback(dragMotionCallback, this);
        }
        pcRoot->addChild(pcEditNode);
    }
    else {
        ViewProviderPart::setEdit(ModNum);
    }

    return true;
}
示例#19
0
void PointsGrid::SearchNearestFromPoint (const Base::Vector3d &rclPt, std::set<unsigned long> &raclInd) const
{
  raclInd.clear();
  Base::BoundBox3d  clBB = GetBoundBox();

  if (clBB.IsInBox(rclPt) == true)
  { // Punkt liegt innerhalb
    unsigned long ulX, ulY, ulZ;
    Position(rclPt, ulX, ulY, ulZ);
    //int nX = ulX, nY = ulY, nZ = ulZ;
    unsigned long ulLevel = 0;
    while (raclInd.size() == 0)
      GetHull(ulX, ulY, ulZ, ulLevel++, raclInd);
    GetHull(ulX, ulY, ulZ, ulLevel, raclInd);
  }
  else
  { // Punkt ausserhalb
    Base::BoundBox3d::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.GetCenter() - rclPt);
    switch (tSide)
    {
      case Base::BoundBox3d::RIGHT:
      {
        int nX = 0;
        while (raclInd.size() == 0)
        {
          for (unsigned long i = 0; i < _ulCtGridsY; i++)
          {
            for (unsigned long j = 0; j < _ulCtGridsZ; j++)
              raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
          }
          nX++;
        }
        break;
      }
      case Base::BoundBox3d::LEFT:
      {
        int nX = _ulCtGridsX - 1;
        while (raclInd.size() == 0)
        {
          for (unsigned long i = 0; i < _ulCtGridsY; i++)
          {
            for (unsigned long j = 0; j < _ulCtGridsZ; j++)
              raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
          }
          nX++;
        }
        break;
      }
      case Base::BoundBox3d::TOP:
      {
        int nY = 0;
        while (raclInd.size() == 0)
        {
          for (unsigned long i = 0; i < _ulCtGridsX; i++)
          {
            for (unsigned long j = 0; j < _ulCtGridsZ; j++)
              raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
          }
          nY++;
        }
        break;
      }
      case Base::BoundBox3d::BOTTOM:
      {
        int nY = _ulCtGridsY - 1;
        while (raclInd.size() == 0)
        {
          for (unsigned long i = 0; i < _ulCtGridsX; i++)
          {
            for (unsigned long j = 0; j < _ulCtGridsZ; j++)
              raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
          }
          nY--;
        }
        break;
      }
      case Base::BoundBox3d::BACK:
      {
        int nZ = 0;
        while (raclInd.size() == 0)
        {
          for (unsigned long i = 0; i < _ulCtGridsX; i++)
          {
            for (unsigned long j = 0; j < _ulCtGridsY; j++)
              raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
          }
          nZ++;
        }
        break;
      }
      case Base::BoundBox3d::FRONT:
      {
        int nZ = _ulCtGridsZ - 1;
        while (raclInd.size() == 0)
        {
          for (unsigned long i = 0; i < _ulCtGridsX; i++)
          {
            for (unsigned long j = 0; j < _ulCtGridsY; j++)
              raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
          }
          nZ--;
        }
        break;
      }

      default:
        break;
    }
  }
}
示例#20
0
Base::BoundBox3d GeometryObject::boundingBoxOfBspline(const BSpline *spline) const
{
    Base::BoundBox3d bb;
    for (std::vector<BezierSegment>::const_iterator segItr( spline->segments.begin() );
            segItr != spline->segments.end(); ++segItr) {
        switch (segItr->poles) {
        case 0:   // Degenerate, but safe ignore
            break;
        case 2:   // Degenerate - straight line
            bb.Add(Base::Vector3d( segItr->pnts[1].fX,
                                   segItr->pnts[1].fY,
                                   0 ));
        // fall through
        case 1:   // Degenerate - just a point
            bb.Add(Base::Vector3d( segItr->pnts[0].fX,
                                   segItr->pnts[0].fY,
                                   0 ));
            break;
        case 3: {
            double
            px[3] = { segItr->pnts[0].fX,
                      segItr->pnts[1].fX,
                      segItr->pnts[2].fX
                    },
                    py[3] = { segItr->pnts[0].fY,
                              segItr->pnts[1].fY,
                              segItr->pnts[2].fY
                            },
                            slns[4] = { 0, 1 }; // Consider the segment's end points

            // if's are to prevent problems with divide-by-0
            if ((2 * px[1] - px[0] - px[2]) == 0) {
                slns[2] = -1;
            } else {
                slns[2] = (px[1] - px[0]) / (2 * px[1] - px[0] - px[2]);
            }
            if ((2 * py[1] - py[0] - py[2]) == 0) {
                slns[3] = -1;
            } else {
                slns[3] = (py[1] - py[0]) / (2 * py[1] - py[0] - py[2]);
            }

            // evaluate B(t) at the endpoints and zeros
            for (int s(0); s < 4; ++s) {
                double t( slns[s] );
                if (t < 0 || t > 1) {
                    continue;
                }
                double tx( px[0] * (1 - t) * (1 - t) +
                           px[1] * 2 * (1 - t) * t +
                           px[2] * t * t ),
                           ty( py[0] * (1 - t) * (1 - t) +
                               py[1] * 2 * (1 - t) * t +
                               py[2] * t * t );
                bb.Add( Base::Vector3d(tx, ty, 0) );
            }
        }
        break;
        case 4: {
            double
            px[4] = { segItr->pnts[0].fX,
                      segItr->pnts[1].fX,
                      segItr->pnts[2].fX,
                      segItr->pnts[3].fX
                    },
                    py[4] = { segItr->pnts[0].fY,
                              segItr->pnts[1].fY,
                              segItr->pnts[2].fY,
                              segItr->pnts[3].fY
                            },
                            // If B(t) is the cubic Bezier, find t where B'(t) == 0
                            //
                            // For control points P0-P3, B'(t) works out to be:
                            // B'(t) = t^2 * (-3P0 + 9P1 - 9P2 + 3P3) +
                            //          t  * (6P0 - 12P1 + 6P2) +
                            //          3  * (P1 - P0)
                            //
                            // So, we use the quadratic formula!
                            ax = -3 * px[0] + 9 * px[1] - 9 * px[2] + 3 * px[3],
                            ay = -3 * py[0] + 9 * py[1] - 9 * py[2] + 3 * py[3],
                            bx = 6 * px[0] - 12 * px[1] + 6 * px[2],
                            by = 6 * py[0] - 12 * py[1] + 6 * py[2],
                            cx = 3 * px[1] - 3 * px[0],
                            cy = 3 * py[1] - 3 * py[0],

                            slns[6] = { 0, 1 }; // Consider the segment's end points

            // if's are to prevent problems with divide-by-0 and NaN
            if ( (2 * ax) == 0 || (bx * bx - 4 * ax * cx) < 0 ) {
                slns[2] = -1;
                slns[3] = -1;
            } else {
                slns[2] = (-bx + sqrt(bx * bx - 4 * ax * cx)) / (2 * ax);
                slns[3] = (-bx - sqrt(bx * bx - 4 * ax * cx)) / (2 * ax);
            }
            if ((2 * ay) == 0 || (by * by - 4 * ay * cy) < 0 ) {
                slns[4] = -1;
                slns[5] = -1;
            } else {
                slns[4] = (-by + sqrt(by * by - 4 * ay * cy)) / (2 * ay);
                slns[5] = (-by - sqrt(by * by - 4 * ay * cy)) / (2 * ay);
            }

            // evaluate B(t) at the endpoints and zeros
            for (int s(0); s < 6; ++s) {
                double t( slns[s] );
                if (t < 0 || t > 1) {
                    continue;
                }
                double tx( px[0] * (1 - t) * (1 - t) * (1 - t) +
                           px[1] * 3 * (1 - t) * (1 - t) * t +
                           px[2] * 3 * (1 - t) * t * t +
                           px[3] * t * t * t ),
                           ty( py[0] * (1 - t) * (1 - t) * (1 - t) +
                               py[1] * 3 * (1 - t) * (1 - t) * t +
                               py[2] * 3 * (1 - t) * t * t +
                               py[3] * t * t * t );
                bb.Add( Base::Vector3d(tx, ty, 0) );
            }

        }
        break;
        default:
            throw Base::Exception("Invalid degree bezier segment in GeometryObject::calcBoundingBox");
        }
    }
    return bb;
}