| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| |
|
| | #include <BRepGProp.hxx>
|
| | #include <GProp_GProps.hxx>
|
| | #include <Precision.hxx>
|
| |
|
| |
|
| | #include "FeatureMultiTransform.h"
|
| | #include "FeatureAddSub.h"
|
| | #include "FeatureScaled.h"
|
| |
|
| |
|
| | using namespace PartDesign;
|
| |
|
| | namespace PartDesign
|
| | {
|
| |
|
| |
|
| | PROPERTY_SOURCE(PartDesign::MultiTransform, PartDesign::Transformed)
|
| |
|
| | MultiTransform::MultiTransform()
|
| | {
|
| | ADD_PROPERTY(Transformations, (nullptr));
|
| | Transformations.setSize(0);
|
| | }
|
| |
|
| | void MultiTransform::positionBySupport()
|
| | {
|
| | PartDesign::Transformed::positionBySupport();
|
| | std::vector<App::DocumentObject*> transFeatures = Transformations.getValues();
|
| | for (auto f : transFeatures) {
|
| | auto transFeature = freecad_cast<PartDesign::Transformed*>(f);
|
| | if (!transFeature) {
|
| | throw Base::TypeError("Transformation features must be subclasses of Transformed");
|
| | }
|
| |
|
| | transFeature->Placement.setValue(this->Placement.getValue());
|
| |
|
| |
|
| |
|
| | if (this->isRecomputing()) {
|
| | transFeature->purgeTouched();
|
| | }
|
| | }
|
| | }
|
| |
|
| | short MultiTransform::mustExecute() const
|
| | {
|
| | if (Transformations.isTouched()) {
|
| | return 1;
|
| | }
|
| | return Transformed::mustExecute();
|
| | }
|
| |
|
| | const std::list<gp_Trsf> MultiTransform::getTransformations(
|
| | const std::vector<App::DocumentObject*> originals
|
| | )
|
| | {
|
| | std::vector<App::DocumentObject*> transFeatures = Transformations.getValues();
|
| |
|
| | gp_Pnt cog;
|
| | if (!originals.empty()) {
|
| |
|
| |
|
| | if (auto addFeature = freecad_cast<PartDesign::FeatureAddSub*>(originals.front())) {
|
| | TopoDS_Shape original = addFeature->AddSubShape.getShape().getShape();
|
| |
|
| | GProp_GProps props;
|
| | BRepGProp::VolumeProperties(original, props);
|
| | cog = props.CentreOfMass();
|
| | }
|
| | }
|
| |
|
| | std::list<gp_Trsf> result;
|
| | std::list<gp_Pnt> cogs;
|
| |
|
| | for (auto const& f : transFeatures) {
|
| | auto transFeature = freecad_cast<PartDesign::Transformed*>(f);
|
| | if (!transFeature) {
|
| | throw Base::TypeError("Transformation features must be subclasses of Transformed");
|
| | }
|
| |
|
| | std::list<gp_Trsf> newTransformations = transFeature->getTransformations(originals);
|
| | if (result.empty()) {
|
| |
|
| | result = newTransformations;
|
| | for (auto nt : newTransformations) {
|
| | cogs.push_back(cog.Transformed(nt));
|
| | }
|
| | }
|
| | else {
|
| |
|
| |
|
| | std::list<gp_Trsf> oldTransformations;
|
| | result.swap(oldTransformations);
|
| | std::list<gp_Pnt> oldCogs;
|
| | cogs.swap(oldCogs);
|
| |
|
| | if (transFeature->is<PartDesign::Scaled>()) {
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | if (newTransformations.empty()) {
|
| | throw Base::ValueError(
|
| | "Number of occurrences must be a divisor of previous "
|
| | "number of occurrences"
|
| | );
|
| | }
|
| | if (oldTransformations.size() % newTransformations.size() != 0) {
|
| | throw Base::ValueError(
|
| | "Number of occurrences must be a divisor of previous "
|
| | "number of occurrences"
|
| | );
|
| | }
|
| |
|
| | unsigned sliceLength = oldTransformations.size() / newTransformations.size();
|
| | auto ot = oldTransformations.begin();
|
| | auto oc = oldCogs.begin();
|
| |
|
| | for (auto const& nt : newTransformations) {
|
| | for (unsigned s = 0; s < sliceLength; s++) {
|
| | gp_Trsf trans;
|
| | double factor = nt.ScaleFactor();
|
| |
|
| | if (factor > Precision::Confusion()) {
|
| | trans.SetScale(*oc, factor);
|
| |
|
| | trans = trans * (*ot);
|
| | cogs.push_back(*oc);
|
| | }
|
| | else {
|
| | trans = nt * (*ot);
|
| | cogs.push_back(oc->Transformed(nt));
|
| | }
|
| | result.push_back(trans);
|
| | ++ot;
|
| | ++oc;
|
| | }
|
| | }
|
| | }
|
| | else {
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | for (auto const& nt : newTransformations) {
|
| | auto oc = oldCogs.begin();
|
| |
|
| | for (auto const& ot : oldTransformations) {
|
| | result.push_back(nt * ot);
|
| | cogs.push_back(oc->Transformed(nt));
|
| | ++oc;
|
| | }
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | }
|
| | }
|
| |
|
| | return result;
|
| | }
|
| |
|
| | }
|
| |
|