OriginGroup: add new abstraction layer between the Part and the GeoFeatureGroup

This commit is contained in:
Alexander Golubev
2015-09-02 07:22:54 +03:00
committed by Stefan Tröger
parent 59ca9212d6
commit 2c2d155ee9
33 changed files with 835 additions and 557 deletions

View File

@@ -76,7 +76,6 @@
#include <Base/UnitPy.h>
#include "GeoFeature.h"
#include "GeoFeatureGroup.h"
#include "FeatureTest.h"
#include "FeaturePython.h"
#include "ComplexGeoData.h"
@@ -95,8 +94,10 @@
#include "Annotation.h"
#include "MeasureDistance.h"
#include "Placement.h"
#include "OriginFeature.h"
#include "GeoFeatureGroup.h"
#include "OriginGroup.h"
#include "Part.h"
#include "OriginFeature.h"
#include "Origin.h"
#include "MaterialObject.h"
#include "Expression.h"
@@ -1122,8 +1123,6 @@ void Application::initTypes(void)
App ::Document ::init();
App ::DocumentObjectGroup ::init();
App ::DocumentObjectGroupPython ::init();
App ::GeoFeatureGroup ::init();
App ::GeoFeatureGroupPython ::init();
App ::DocumentObjectFileIncluded::init();
App ::InventorObject ::init();
App ::VRMLObject ::init();
@@ -1136,6 +1135,9 @@ void Application::initTypes(void)
App ::OriginFeature ::init();
App ::Plane ::init();
App ::Line ::init();
App ::GeoFeatureGroup ::init();
App ::GeoFeatureGroupPython ::init();
App ::OriginGroup ::init();
App ::Part ::init();
App ::Origin ::init();

View File

@@ -35,6 +35,7 @@ generate_from_xml(DocumentObjectPy)
generate_from_xml(DocumentObjectGroupPy)
generate_from_xml(GeoFeaturePy)
generate_from_xml(GeoFeatureGroupPy)
generate_from_xml(OriginGroupPy)
generate_from_xml(PartPy)
generate_from_xml(ComplexGeoDataPy)
@@ -49,6 +50,7 @@ SET(FreeCADApp_XML_SRCS
DocumentObjectPy.xml
GeoFeaturePy.xml
GeoFeatureGroupPy.xml
OriginGroupPy.xml
PartPy.xml
DocumentPy.xml
PropertyContainerPy.xml
@@ -65,7 +67,6 @@ SET(Document_CPP_SRCS
DocumentObjectFileIncluded.cpp
DocumentObjectGroup.cpp
DocumentObjectGroupPyImp.cpp
PartPyImp.cpp
GeoFeaturePyImp.cpp
DocumentObjectPyImp.cpp
DocumentObserver.cpp
@@ -77,6 +78,9 @@ SET(Document_CPP_SRCS
GeoFeature.cpp
GeoFeatureGroupPyImp.cpp
GeoFeatureGroup.cpp
OriginGroupPyImp.cpp
OriginGroup.cpp
PartPyImp.cpp
Part.cpp
Origin.cpp
Path.cpp
@@ -108,6 +112,7 @@ SET(Document_HPP_SRCS
FeatureTest.h
GeoFeature.h
GeoFeatureGroup.h
OriginGroup.h
Part.h
Origin.h
Path.h

View File

@@ -60,14 +60,84 @@ void GeoFeatureGroup::transformPlacement(const Base::Placement &transform)
this->Placement.setValue(plm);
}
GeoFeatureGroup* GeoFeatureGroup::getGroupOfObject(const DocumentObject* obj)
std::vector<App::DocumentObject*> GeoFeatureGroup::getGeoSubObjects () const {
const auto & objs = Group.getValues();
std::set<const App::DocumentObjectGroup*> processedGroups;
std::set<App::DocumentObject*> rvSet;
std::set<App::DocumentObject*> curSearchSet (objs.begin(), objs.end());
processedGroups.insert ( this );
while ( !curSearchSet.empty() ) {
rvSet.insert ( curSearchSet.begin (), curSearchSet.end () );
std::set<App::DocumentObject*> nextSearchSet;
for ( auto obj: curSearchSet) {
if ( isNonGeoGroup (obj) ) {
const App::DocumentObjectGroup *grp = static_cast<const App::DocumentObjectGroup *> (obj);
// Check if we havent already processed the element may happen in case of nontree structure
// Note: if the condition is false this generally indicates malformed structure
if ( processedGroups.find (grp) == processedGroups.end() ) {
processedGroups.insert ( grp );
const auto & objs = grp->Group.getValues();
nextSearchSet.insert (objs.begin(), objs.end());
}
}
}
nextSearchSet.swap (curSearchSet);
}
return std::vector<App::DocumentObject*> ( rvSet.begin(), rvSet.end() );
}
bool GeoFeatureGroup::geoHasObject (const DocumentObject* obj) const {
const auto & objs = Group.getValues();
if (!obj) {
return false;
}
std::set<const App::DocumentObjectGroup*> processedGroups;
std::set<const App::DocumentObject*> curSearchSet (objs.begin(), objs.end());
processedGroups.insert ( this );
while ( !curSearchSet.empty() ) {
if ( curSearchSet.find (obj) != curSearchSet.end() ) {
return true;
}
std::set<const App::DocumentObject*> nextSearchSet;
for ( auto obj: curSearchSet) {
if ( isNonGeoGroup (obj) ) {
const App::DocumentObjectGroup *grp = static_cast<const App::DocumentObjectGroup *> (obj);
if ( processedGroups.find (grp) == processedGroups.end() ) {
processedGroups.insert ( grp );
const auto & objs = grp->Group.getValues();
nextSearchSet.insert (objs.begin(), objs.end());
}
}
}
nextSearchSet.swap (curSearchSet);
}
return false;
}
GeoFeatureGroup* GeoFeatureGroup::getGroupOfObject(const DocumentObject* obj, bool indirect)
{
const Document* doc = obj->getDocument();
std::vector<DocumentObject*> grps = doc->getObjectsOfType(GeoFeatureGroup::getClassTypeId());
for (std::vector<DocumentObject*>::const_iterator it = grps.begin(); it != grps.end(); ++it) {
GeoFeatureGroup* grp = (GeoFeatureGroup*)(*it);
if (grp->hasObject(obj))
return grp;
if ( indirect ) {
if (grp->geoHasObject(obj)) {
return grp;
}
} else {
if (grp->hasObject(obj)) {
return grp;
}
}
}
return 0;

View File

@@ -46,8 +46,7 @@ public:
/**
* @brief transformPlacement applies transform to placement of this shape.
* Override this function to propagate the change of placement to base
* features, for example. By the time of writing this comment, the function
* was only called by alignment task (Edit->Alignment)
* features.
* @param transform (input).
*/
virtual void transformPlacement(const Base::Placement &transform);
@@ -55,13 +54,28 @@ public:
GeoFeatureGroup(void);
virtual ~GeoFeatureGroup();
/// Returns all geometrically controlled objects: all objects of this group and it's non-geo subgroups
std::vector<App::DocumentObject*> getGeoSubObjects () const;
/// Returns true if either the group or one of it's non-geo subgroups has the object
bool geoHasObject (const DocumentObject* obj) const;
/** Returns the geo feature group which contains this object.
* In case this object is not part of any geoFeatureGroup 0 is returned.
* Unlike DocumentObjectGroup::getGroupOfObject serches only for GeoFeatureGroups
* @param obj the object to search for
* @param indirect if true return if the group that so-called geoHas the object, @see geoHasObject()
* default is true
*/
static GeoFeatureGroup* getGroupOfObject(const DocumentObject* obj);
static GeoFeatureGroup* getGroupOfObject(const DocumentObject* obj, bool indirect=true);
/// returns the type name of the ViewProvider
/// Returns true if the given DocumentObject is DocumentObjectGroup but not GeoFeatureGroup
static bool isNonGeoGroup(const DocumentObject* obj) {
return obj->isDerivedFrom ( App::DocumentObjectGroup::getClassTypeId () ) &&
!obj->isDerivedFrom ( App::GeoFeatureGroup::getClassTypeId () );
}
/// Returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const {
return "Gui::ViewProviderGeoFeatureGroup";
}

View File

@@ -11,7 +11,7 @@
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
<UserDocu>This class handles document objects in Part</UserDocu>
<UserDocu>This class handles placeable group of document objects</UserDocu>
</Documentation>
</PythonExport>

View File

@@ -32,7 +32,7 @@
#include <Base/Placement.h>
#include <App/Document.h>
#include <App/OriginFeature.h>
#include "OriginFeature.h"
#include "Origin.h"
@@ -123,7 +123,7 @@ App::DocumentObjectExecReturn *Origin::execute(void) {
setError ();
return new App::DocumentObjectExecReturn ( ex.what () );
}
// purgeError ();
return DocumentObject::execute ();
}

122
src/App/OriginGroup.cpp Normal file
View File

@@ -0,0 +1,122 @@
/***************************************************************************
* Copyright (c) Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "OriginGroup.h"
#ifndef _PreComp_
#endif
#include <Base/Exception.h>
#include <App/Document.h>
#include "Origin.h"
#include "GeoFeature.h"
using namespace App;
PROPERTY_SOURCE(App::OriginGroup, App::GeoFeatureGroup);
OriginGroup::OriginGroup () {
ADD_PROPERTY_TYPE ( Origin, (0), 0, App::Prop_Hidden, "Origin linked to the group" );
}
OriginGroup::~OriginGroup ()
{ }
App::Origin *OriginGroup::getOrigin () const {
App::DocumentObject *originObj = Origin.getValue ();
if ( !originObj ) {
std::stringstream err;
err << "Can't find Origin for \"" << getNameInDocument () << "\"";
throw Base::Exception ( err.str().c_str () );
} else if (! originObj->isDerivedFrom ( App::Origin::getClassTypeId() ) ) {
std::stringstream err;
err << "Bad object \"" << originObj->getNameInDocument () << "\"(" << originObj->getTypeId().getName()
<< ") linked to the Origin of \"" << getNameInDocument () << "\"";
throw Base::Exception ( err.str().c_str () );
} else {
return static_cast<App::Origin *> ( originObj );
}
}
App::OriginGroup *OriginGroup::getGroupOfObject (const DocumentObject* obj, bool indirect) {
const Document* doc = obj->getDocument();
std::vector<DocumentObject*> grps = doc->getObjectsOfType ( OriginGroup::getClassTypeId() );
for (auto grpObj: grps) {
OriginGroup* grp = static_cast <OriginGroup* >(grpObj);
if ( indirect ) {
if ( grp->geoHasObject (obj) ) {
return grp;
}
} else {
if ( grp->hasObject (obj) ) {
return grp;
}
}
}
return 0;
}
short OriginGroup::mustExecute() const {
if (Origin.isTouched ()) {
return 1;
} else {
return GeoFeatureGroup::mustExecute();
}
}
App::DocumentObjectExecReturn *OriginGroup::execute() {
try { // try to find all base axis and planes in the origin
App::Origin *origin = getOrigin ();
} catch (const Base::Exception &ex) {
setError ();
return new App::DocumentObjectExecReturn ( ex.what () );
}
return GeoFeatureGroup::execute ();
}
void OriginGroup::setupObject () {
App::Document *doc = getDocument ();
std::string objName = std::string ( getNameInDocument()).append ( "Origin" );
App::DocumentObject *originObj = doc->addObject ( "App::Origin", objName.c_str () );
assert ( originObj && originObj->isDerivedFrom ( App::Origin::getClassTypeId () ) );
Origin.setValue (originObj);
GeoFeatureGroup::setupObject ();
}
void OriginGroup::unsetupObject () {
App::DocumentObject *origin = Origin.getValue ();
if (origin && !origin->isDeleting ()) {
origin->getDocument ()->remObject (origin->getNameInDocument());
}
GeoFeatureGroup::unsetupObject ();
}

76
src/App/OriginGroup.h Normal file
View File

@@ -0,0 +1,76 @@
/***************************************************************************
* Copyright (c) Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef ORIGINGROUP_H_QHTU73IF
#define ORIGINGROUP_H_QHTU73IF
#include "GeoFeatureGroup.h"
#include "PropertyLinks.h"
namespace App {
class Origin;
/**
* Represents an abstact placeable group of objects with an associated Origin
*/
class OriginGroup: public App::GeoFeatureGroup
{
PROPERTY_HEADER(App::OriginGroup);
public:
OriginGroup ();
virtual ~OriginGroup ();
/// Returns the origin link or throws an exception
App::Origin *getOrigin () const;
/// returns the type name of the ViewProvider
virtual const char* getViewProviderName () const {
return "Gui::ViewProviderOriginGroup";
}
/**
* Returns the origin group which contains this object.
* In case this object is not part of any geoFeatureGroup 0 is returned.
* @param obj the object to search for
* @param indirect if true return if the group that so-called geoHas the object, @see geoHasObject()
* default is true
*/
static OriginGroup* getGroupOfObject (const DocumentObject* obj, bool indirect=true);
/// Returns true on changing OriginFeature set
virtual short mustExecute () const;
/// Origin linked to the group
PropertyLink Origin;
protected:
/// Checks integrity of the Origin
virtual App::DocumentObjectExecReturn *execute ();
/// Creates the corresponding Origin object
virtual void setupObject ();
/// Removes all planes and axis if they are still linked to the document
virtual void unsetupObject ();
};
} /* App */
#endif /* end of include guard: ORIGINGROUP_H_QHTU73IF */

19
src/App/OriginGroupPy.xml Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="GeoFeatureGroupPy"
Name="OriginGroupPy"
Twin="OriginGroup"
TwinPointer="OriginGroup"
Include="App/OriginGroup.h"
Namespace="App"
FatherInclude="App/GeoFeatureGroupPy.h"
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="Alexander Golubev" EMail="fatzer2@gmail.com" />
<UserDocu>This class handles placable group of document objects with an Origin</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>

View File

@@ -0,0 +1,34 @@
#include "PreCompiled.h"
#include "App/OriginGroup.h"
// inclusion of the generated files (generated out of OriginGroupPy.xml)
#include "OriginGroupPy.h"
#include "OriginGroupPy.cpp"
using namespace App;
// returns a string which represents the object e.g. when printed in python
std::string OriginGroupPy::representation(void) const
{
return std::string("<OriginGroup object>");
}
PyObject *OriginGroupPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int OriginGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -35,18 +35,14 @@
using namespace App;
PROPERTY_SOURCE(App::Part, App::GeoFeatureGroup)
PROPERTY_SOURCE(App::Part, App::OriginGroup)
//===========================================================================
// Feature
// Part
//===========================================================================
const char* Part::BaseplaneTypes[3] = {"XY_Plane", "XZ_Plane", "YZ_Plane"};
const char* Part::BaselineTypes[3] = {"X_Axis", "Y_Axis", "Z_Axis"};
Part::Part(void)
{
ADD_PROPERTY(Type,(""));

View File

@@ -24,7 +24,7 @@
#ifndef APP_Part_H
#define APP_Part_H
#include "GeoFeatureGroup.h"
#include "OriginGroup.h"
#include "PropertyLinks.h"
@@ -35,7 +35,7 @@ namespace App
/** Base class of all geometric document objects.
*/
class AppExport Part : public App::GeoFeatureGroup
class AppExport Part : public App::OriginGroup
{
PROPERTY_HEADER(App::Part);
@@ -75,7 +75,6 @@ public:
App::PropertyColor Color;
//@}
/// Constructor
Part(void);
virtual ~Part();
@@ -85,11 +84,7 @@ public:
return "Gui::ViewProviderPart";
}
virtual PyObject *getPyObject(void);
static const char* BaseplaneTypes[3];
static const char* BaselineTypes[3];
};
//typedef App::FeaturePythonT<Part> PartPython;

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="GeoFeatureGroupPy"
Father="OriginGroupPy"
Name="PartPy"
Twin="Part"
TwinPointer="Part"
Include="App/Part.h"
Namespace="App"
FatherInclude="App/GeoFeatureGroupPy.h"
FatherInclude="App/OriginGroupPy.h"
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />