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