1 /* This file is part of Step.
2    Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
3 
4    Step is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8 
9    Step is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with Step; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18 
19 #include "worldfactory.h"
20 #include "worldgraphics.h"
21 #include "worldmodel.h"
22 
23 #include <stepcore/world.h>
24 #include <stepcore/particle.h>
25 #include <stepcore/rigidbody.h>
26 #include <stepcore/gas.h>
27 #include <stepcore/softbody.h>
28 #include <stepcore/gravitation.h>
29 #include <stepcore/coulombforce.h>
30 #include <stepcore/spring.h>
31 #include <stepcore/motor.h>
32 #include <stepcore/gslsolver.h>
33 #include <stepcore/eulersolver.h>
34 #include <stepcore/collisionsolver.h>
35 #include <stepcore/constraintsolver.h>
36 #include <stepcore/joints.h>
37 #include <stepcore/tool.h>
38 #include <stepcore/types.h>
39 
40 #include "particlegraphics.h"
41 #include "polygongraphics.h"
42 #include "gasgraphics.h"
43 #include "softbodygraphics.h"
44 #include "springgraphics.h"
45 #include "motorgraphics.h"
46 #include "jointgraphics.h"
47 #include "toolgraphics.h"
48 
49 #include <QIcon>
50 
51 #include <KIconLoader>
52 
53 template<typename T>
newItemCreatorHelper(const QString & className,WorldModel * worldModel,WorldScene * worldScene)54 ItemCreator* newItemCreatorHelper(const QString& className,
55                     WorldModel* worldModel, WorldScene* worldScene)
56 {
57     return new T(className, worldModel, worldScene);
58 }
59 
60 template<typename T>
newGraphicsItemHelper(StepCore::Item * item,WorldModel * worldModel)61 StepGraphicsItem* newGraphicsItemHelper(StepCore::Item* item, WorldModel* worldModel)
62 {
63     return new T(item, worldModel);
64 }
65 
66 template<typename T>
newItemMenuHandlerHelper(StepCore::Object * object,WorldModel * worldModel,QObject * parent)67 ItemMenuHandler* newItemMenuHandlerHelper(StepCore::Object* object, WorldModel* worldModel, QObject* parent)
68 {
69     return new T(object, worldModel, parent);
70 }
71 
72 
WorldFactory()73 WorldFactory::WorldFactory()
74 {
75     _nullIcon = new QIcon();
76 
77     #define ___REGISTER_EXT(Class, newGraphicsCreator, newGraphicsItem, newItemMenuHandler) \
78         static ExtMetaObject extMetaObject ## Class = \
79                 { newGraphicsCreator, newGraphicsItem, newItemMenuHandler, false, NULL }; \
80         registerMetaObject(StepCore::Class::staticMetaObject()); \
81         _extMetaObjects.insert(StepCore::Class::staticMetaObject(), &extMetaObject ## Class); \
82         _orderedMetaObjects.push_back(QString(StepCore::Class::staticMetaObject()->className())); \
83         loadIcon(StepCore::Class::staticMetaObject(), const_cast<ExtMetaObject*>(&extMetaObject ## Class))
84 
85     #define ___REGISTER_EXT_E(Class, newGraphicsCreator, newGraphicsItem, newItemMenuHandler) \
86         ___REGISTER_EXT(Class, newGraphicsCreator, newGraphicsItem, newItemMenuHandler); \
87         registerMetaObject(StepCore::Class##Errors::staticMetaObject())
88 
89     #define __REGISTER(Class) ___REGISTER_EXT(Class, NULL, NULL, NULL)
90     #define __REGISTER_E(Class) ___REGISTER_EXT_E(Class, NULL, NULL, NULL)
91 
92     #define __REGISTER_EXT(Class, GraphicsCreator, GraphicsItem, ItemMenuHandler) \
93         ___REGISTER_EXT(Class, newItemCreatorHelper<GraphicsCreator>, \
94                    newGraphicsItemHelper<GraphicsItem>, newItemMenuHandlerHelper<ItemMenuHandler>)
95 
96     #define __REGISTER_EXT_E(Class, GraphicsCreator, GraphicsItem, ItemMenuHandler) \
97         __REGISTER_EXT(Class, GraphicsCreator, GraphicsItem, ItemMenuHandler); \
98         registerMetaObject(StepCore::Class##Errors::staticMetaObject())
99 
100     #define __ADD_TO_PALETTE(Class) \
101         _paletteMetaObjects.push_back(QString(StepCore::Class::staticMetaObject()->className()))
102 
103     #define __ADD_SEPARATOR \
104         _paletteMetaObjects.push_back(QString())
105 
106     __REGISTER_E(Object);
107 
108     __REGISTER(Item);
109     __REGISTER(World);
110     __REGISTER(ItemGroup);
111     __REGISTER(Body);
112     __REGISTER(Force);
113     __REGISTER(Solver);
114     __REGISTER(CollisionSolver);
115     __REGISTER(ConstraintSolver);
116 
117     __REGISTER_EXT_E(Particle, ItemCreator, ParticleGraphicsItem, ItemMenuHandler);
118     __REGISTER_EXT_E(ChargedParticle, ItemCreator, ParticleGraphicsItem, ItemMenuHandler);
119 
120     __REGISTER_EXT(Disk, DiskCreator, DiskGraphicsItem, ItemMenuHandler);
121     __REGISTER_EXT(Box, BoxCreator, BoxGraphicsItem, ItemMenuHandler);
122     __REGISTER_EXT(Polygon, PolygonCreator, PolygonGraphicsItem, ItemMenuHandler);
123 
124     __REGISTER_EXT(GasParticle, ItemCreator, ParticleGraphicsItem, ItemMenuHandler);
125     __REGISTER(GasLJForce);
126     __REGISTER_EXT(Gas, GasCreator, GasGraphicsItem, GasMenuHandler);
127 
128     __REGISTER_EXT(SoftBodySpring, SpringCreator, SoftBodySpringGraphicsItem, ItemMenuHandler);
129     __REGISTER_EXT(SoftBodyParticle, ItemCreator, SoftBodyParticleGraphicsItem, ItemMenuHandler);
130     __REGISTER_EXT(SoftBody, SoftBodyCreator, SoftBodyGraphicsItem, SoftBodyMenuHandler);
131 
132     __REGISTER_EXT_E(Spring, SpringCreator, SpringGraphicsItem, ItemMenuHandler);
133     __REGISTER_EXT(LinearMotor, LinearMotorCreator, LinearMotorGraphicsItem, ItemMenuHandler);
134     __REGISTER_EXT(CircularMotor, CircularMotorCreator, CircularMotorGraphicsItem, ItemMenuHandler);
135 
136     __REGISTER_E(WeightForce);
137     __REGISTER_E(GravitationForce);
138     __REGISTER_E(CoulombForce);
139 
140     __REGISTER_EXT(Anchor, AnchorCreator, AnchorGraphicsItem, ItemMenuHandler);
141     __REGISTER_EXT(Pin, PinCreator, PinGraphicsItem, ItemMenuHandler);
142     __REGISTER_EXT(Stick, StickCreator, StickGraphicsItem, ItemMenuHandler);
143     //__REGISTER_EXT(Rope, StickCreator, StickGraphicsItem, ItemMenuHandler);
144 
145     __REGISTER(EulerSolver);
146     __REGISTER(AdaptiveEulerSolver);
147 
148     __REGISTER(GJKCollisionSolver);
149     __REGISTER(CGConstraintSolver);
150 
151 #ifdef STEPCORE_WITH_GSL
152     __REGISTER(GslRK2Solver);
153     __REGISTER(GslRK4Solver);
154     __REGISTER(GslRKF45Solver);
155     __REGISTER(GslRKCKSolver);
156     __REGISTER(GslRK8PDSolver);
157     __REGISTER(GslRK2IMPSolver);
158     __REGISTER(GslRK4IMPSolver);
159 
160     __REGISTER(GslAdaptiveRK2Solver);
161     __REGISTER(GslAdaptiveRK4Solver);
162     __REGISTER(GslAdaptiveRKF45Solver);
163     __REGISTER(GslAdaptiveRKCKSolver);
164     __REGISTER(GslAdaptiveRK8PDSolver);
165     __REGISTER(GslAdaptiveRK2IMPSolver);
166     __REGISTER(GslAdaptiveRK4IMPSolver);
167 #endif
168 
169     __REGISTER(NoteImage);
170     __REGISTER(NoteFormula);
171     __REGISTER_EXT(Note, ItemCreator, NoteGraphicsItem, ItemMenuHandler);
172     __REGISTER_EXT(Meter, ItemCreator, MeterGraphicsItem, MeterMenuHandler);
173     __REGISTER_EXT(Graph, ItemCreator, GraphGraphicsItem, GraphMenuHandler);
174     __REGISTER_EXT(Controller, ItemCreator, ControllerGraphicsItem, ControllerMenuHandler);
175     __REGISTER_EXT(Tracer, TracerCreator, TracerGraphicsItem, TracerMenuHandler);
176 
177     // Palette
178     __ADD_TO_PALETTE(Particle);
179     __ADD_TO_PALETTE(ChargedParticle);
180     __ADD_TO_PALETTE(Disk);
181     __ADD_TO_PALETTE(Box);
182     __ADD_TO_PALETTE(Polygon);
183     __ADD_SEPARATOR;
184 
185     __ADD_TO_PALETTE(Spring);
186     __ADD_TO_PALETTE(LinearMotor);
187     __ADD_TO_PALETTE(CircularMotor);
188     __ADD_SEPARATOR;
189 
190     __ADD_TO_PALETTE(Gas);
191     __ADD_TO_PALETTE(SoftBody);
192     __ADD_SEPARATOR;
193 
194     __ADD_TO_PALETTE(WeightForce);
195     __ADD_TO_PALETTE(GravitationForce);
196     __ADD_TO_PALETTE(CoulombForce);
197     __ADD_SEPARATOR;
198 
199     __ADD_TO_PALETTE(Anchor);
200     __ADD_TO_PALETTE(Pin);
201     __ADD_TO_PALETTE(Stick);
202     //__ADD_TO_PALETTE(Rope);
203     __ADD_SEPARATOR;
204 
205     __ADD_TO_PALETTE(Note);
206     __ADD_TO_PALETTE(Meter);
207     __ADD_TO_PALETTE(Tracer);
208     __ADD_TO_PALETTE(Graph);
209     __ADD_TO_PALETTE(Controller);
210 }
211 
~WorldFactory()212 WorldFactory::~WorldFactory()
213 {
214     delete _nullIcon;
215 }
216 
newItemCreator(const QString & className,WorldModel * worldModel,WorldScene * worldScene) const217 ItemCreator* WorldFactory::newItemCreator(const QString& className,
218                     WorldModel* worldModel, WorldScene* worldScene) const
219 {
220     const StepCore::MetaObject* mObject = metaObject(className);
221     if(!mObject) return NULL;
222     const ExtMetaObject *extMetaObject = _extMetaObjects.value(mObject, NULL);
223     if(extMetaObject && extMetaObject->newItemCreator)
224         return extMetaObject->newItemCreator(className, worldModel, worldScene);
225     else return new ItemCreator(className, worldModel, worldScene);
226 }
227 
newGraphicsItem(StepCore::Item * item,WorldModel * worldModel) const228 StepGraphicsItem* WorldFactory::newGraphicsItem(StepCore::Item* item, WorldModel* worldModel) const
229 {
230     const ExtMetaObject *extMetaObject = _extMetaObjects.value(item->metaObject(), NULL);
231     if(extMetaObject && extMetaObject->newGraphicsItem)
232         return extMetaObject->newGraphicsItem(item, worldModel);
233     return NULL;
234 }
235 
newItemMenuHandler(StepCore::Object * object,WorldModel * worldModel,QObject * parent) const236 ItemMenuHandler* WorldFactory::newItemMenuHandler(StepCore::Object* object, WorldModel* worldModel, QObject* parent) const
237 {
238     const ExtMetaObject *extMetaObject = _extMetaObjects.value(object->metaObject(), NULL);
239     if(extMetaObject && extMetaObject->newItemMenuHandler)
240         return extMetaObject->newItemMenuHandler(object, worldModel, parent);
241     else return new ItemMenuHandler(object, worldModel, parent);
242 }
243 
hasObjectIcon(const StepCore::MetaObject * mObject) const244 bool WorldFactory::hasObjectIcon(const StepCore::MetaObject* mObject) const
245 {
246     const ExtMetaObject *extMetaObject = _extMetaObjects.value(mObject, NULL);
247     if(extMetaObject && extMetaObject->hasIcon) return true;
248     else return false;
249 }
250 
objectIcon(const StepCore::MetaObject * mObject) const251 const QIcon& WorldFactory::objectIcon(const StepCore::MetaObject* mObject) const
252 {
253     const ExtMetaObject *extMetaObject = _extMetaObjects.value(mObject, NULL);
254     if (extMetaObject && extMetaObject->icon)
255 	return *(extMetaObject->icon);
256     else {
257         qWarning("Trying to load icon for unregistered metaObject\n");
258         return *_nullIcon;
259     }
260 }
261 
loadIcon(const StepCore::MetaObject * metaObject,ExtMetaObject * extMetaObject)262 void WorldFactory::loadIcon(const StepCore::MetaObject* metaObject, ExtMetaObject* extMetaObject)
263 {
264     QString iconName = QStringLiteral("step_object_") + metaObject->className();
265     extMetaObject->icon = new QIcon(QIcon::fromTheme(iconName));
266     QString iconPath = KIconLoader::global()->iconPath(iconName, KIconLoader::Small, true);
267     extMetaObject->hasIcon = !iconPath.isEmpty();
268 }
269 
270