App/Origin: big refactoring

- Rebase App::Origin on App::DocumentObject
 - Keep all control over the Origin structure inside the Origin and it's
   ViewProvider
 - Add OriginFeature class as common base for App::Plane and App::Line
 - Rebase App::Plane and App::Line on top of newly created class and
   move to the file.
 - Change Origin's ViewProvider API associated with temporary display
 - Lots of associated changes to files
 - Several minor fixes
 - Lots of new bugs
This commit is contained in:
Alexander Golubev
2015-09-01 05:35:10 +03:00
committed by Stefan Tröger
parent ecbb576330
commit 797d6d3a11
47 changed files with 641 additions and 673 deletions

View File

@@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (c) Stefan Tröger (stefantroeger@gmx.net) 2015 *
* Copyright (c) Stefan Tr<EFBFBD>ger (stefantroeger@gmx.net) 2015 *
* Copyright (c) Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@@ -24,10 +25,14 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <string>
#endif
#include <Base/Exception.h>
#include <Base/Placement.h>
#include <App/Document.h>
#include <App/Plane.h>
#include <App/OriginFeature.h>
#include "Origin.h"
@@ -35,20 +40,138 @@
using namespace App;
PROPERTY_SOURCE(App::Origin, App::GeoFeatureGroup)
PROPERTY_SOURCE(App::Origin, App::DocumentObject)
const char* Origin::AxisRoles[3] = {"X_Axis", "Y_Axis", "Z_Axis"};
const char* Origin::PlaneRoles[3] = {"XY_Plane", "XZ_Plane", "YZ_Plane"};
//===========================================================================
// Feature
//===========================================================================
Origin::Origin(void)
{
Placement.StatusBits.set(3, true);
Origin::Origin(void) {
ADD_PROPERTY_TYPE ( OriginFeatures, (0), 0, App::Prop_Hidden,
"Axis and baseplanes controlled by the origin" );
}
Origin::~Origin(void)
{
{ }
App::OriginFeature *Origin::getOriginFeature( const char *role) const {
const auto & features = OriginFeatures.getValues ();
auto featIt = std::find_if (features.begin(), features.end(),
[role] (App::DocumentObject *obj) {
return obj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) &&
strcmp (static_cast<App::OriginFeature *>(obj)->Role.getValue(), role) == 0;
} );
if (featIt != features.end()) {
return static_cast<App::OriginFeature *>(*featIt);
} else {
std::stringstream err;
err << "Origin \"" << getNameInDocument () << "\" doesn't contain feature with role \""
<< role << '"';
throw Base::Exception ( err.str().c_str () );
}
}
App::Line *Origin::getAxis( const char *role ) const {
App::OriginFeature *feat = getOriginFeature (role);
if ( feat->isDerivedFrom(App::Line::getClassTypeId () ) ) {
return static_cast<App::Line *> (feat);
} else {
std::stringstream err;
err << "Origin \"" << getNameInDocument () << "\" contains bad Axis object for role \""
<< role << '"';
throw Base::Exception ( err.str().c_str () );
}
}
App::Plane *Origin::getPlane( const char *role ) const {
App::OriginFeature *feat = getOriginFeature (role);
if ( feat->isDerivedFrom(App::Plane::getClassTypeId () ) ) {
return static_cast<App::Plane *> (feat);
} else {
std::stringstream err;
err << "Origin \"" << getNameInDocument () << "\" comtains bad Plane object for role \""
<< role << '"';
throw Base::Exception ( err.str().c_str () );
}
}
bool Origin::hasObject (DocumentObject *obj) const {
const auto & features = OriginFeatures.getValues ();
return std::find (features.begin(), features.end(), obj) != features.end ();
}
short Origin::mustExecute(void) const {
if (OriginFeatures.isTouched ()) {
return 1;
} else {
return DocumentObject::mustExecute();
}
}
App::DocumentObjectExecReturn *Origin::execute(void) {
try { // try to find all base axis and planes in the origin
for (const char* role: AxisRoles) {
App::Line *axis = getAxis (role);
assert(axis);
}
for (const char* role: PlaneRoles) {
App::Plane *plane = getPlane (role);
assert(plane);
}
} catch (const Base::Exception &ex) {
setError ();
return new App::DocumentObjectExecReturn ( ex.what () );
}
// purgeError ();
return DocumentObject::execute ();
}
void Origin::setupObject () {
const static struct {
const Base::Type type;
const char *role;
Base::Rotation rot;
} setupData [] = {
{App::Line::getClassTypeId(), "X_Axis", Base::Rotation () },
{App::Line::getClassTypeId(), "Y_Axis", Base::Rotation ( Base::Vector3d (1,1,1), M_PI*2/3 ) },
{App::Line::getClassTypeId(), "Z_Axis", Base::Rotation ( Base::Vector3d (1,1,1), M_PI*4/3 ) },
{App::Plane::getClassTypeId (), "XY_Plane", Base::Rotation () },
{App::Plane::getClassTypeId (), "XZ_Plane", Base::Rotation ( Base::Vector3d (0,1,1), M_PI ), },
{App::Plane::getClassTypeId (), "YZ_Plane", Base::Rotation ( Base::Vector3d (1,1,1), M_PI*2/3 ) },
};
App::Document *doc = getDocument ();
std::vector<App::DocumentObject *> links;
for (auto data: setupData) {
std::string objName = doc->getUniqueObjectName ( data.role );
App::DocumentObject *featureObj = doc->addObject ( data.type.getName(), objName.c_str () );
assert ( featureObj && featureObj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) );
App::OriginFeature *feature = static_cast <App::OriginFeature *> ( featureObj );
feature->Placement.setValue ( Base::Placement ( Base::Vector3d (), data.rot ) );
feature->Role.setValue ( data.role );
links.push_back (feature);
}
OriginFeatures.setValues (links);
}
void Origin::unsetupObject () {
const auto &objsLnk = OriginFeatures.getValues ();
// Copy to set to assert we won't call methode more then one time for each object
std::set<App::DocumentObject *> objs (objsLnk.begin(), objsLnk.end());
// Remove all controlled objects
for (auto obj: objs ) {
// Check that previous deletes wasn't inderectly removed one of our objects
const auto &objsLnk = OriginFeatures.getValues ();
if ( std::find(objsLnk.begin(), objsLnk.end(), obj) != objsLnk.end()) {
if ( ! obj->isDeleting () ) {
obj->getDocument ()->remObject (obj->getNameInDocument());
}
}
}
}