Base::BoundBox3d PropertyPointKernel::getBoundingBox() const { Base::BoundBox3d box; for (PointKernel::const_iterator it = _cPoints->begin(); it != _cPoints->end(); ++it) box.Add(*it); return box; }
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("")); } }
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; }
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; }
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; }
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); }
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)); }
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(); } } }
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; }
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; }
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); }
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; }
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; }
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; } } }
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; }