File indexing completed on 2024-04-28 03:51:22

0001 /*.
0002     SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "worldfactory.h"
0008 #include "worldgraphics.h"
0009 #include "worldmodel.h"
0010 
0011 #include <stepcore/world.h>
0012 #include <stepcore/particle.h>
0013 #include <stepcore/rigidbody.h>
0014 #include <stepcore/gas.h>
0015 #include <stepcore/softbody.h>
0016 #include <stepcore/gravitation.h>
0017 #include <stepcore/coulombforce.h>
0018 #include <stepcore/spring.h>
0019 #include <stepcore/motor.h>
0020 #include <stepcore/gslsolver.h>
0021 #include <stepcore/eulersolver.h>
0022 #include <stepcore/collisionsolver.h>
0023 #include <stepcore/constraintsolver.h>
0024 #include <stepcore/joints.h>
0025 #include <stepcore/tool.h>
0026 #include <stepcore/types.h>
0027 
0028 #include "particlegraphics.h"
0029 #include "polygongraphics.h"
0030 #include "gasgraphics.h"
0031 #include "softbodygraphics.h"
0032 #include "springgraphics.h"
0033 #include "motorgraphics.h"
0034 #include "jointgraphics.h"
0035 #include "toolgraphics.h"
0036 
0037 #include <QIcon>
0038 
0039 #include <KIconLoader>
0040 
0041 template<typename T>
0042 ItemCreator* newItemCreatorHelper(const QString& className,
0043                     WorldModel* worldModel, WorldScene* worldScene)
0044 {
0045     return new T(className, worldModel, worldScene);
0046 }
0047 
0048 template<typename T>
0049 StepGraphicsItem* newGraphicsItemHelper(StepCore::Item* item, WorldModel* worldModel)
0050 {
0051     return new T(item, worldModel);
0052 }
0053 
0054 template<typename T>
0055 ItemMenuHandler* newItemMenuHandlerHelper(StepCore::Object* object, WorldModel* worldModel, QObject* parent)
0056 {
0057     return new T(object, worldModel, parent);
0058 }
0059 
0060 
0061 WorldFactory::WorldFactory()
0062 {
0063     _nullIcon = new QIcon();
0064 
0065     #define ___REGISTER_EXT(Class, newGraphicsCreator, newGraphicsItem, newItemMenuHandler) \
0066         static ExtMetaObject extMetaObject ## Class = \
0067                 { newGraphicsCreator, newGraphicsItem, newItemMenuHandler, false, NULL }; \
0068         registerMetaObject(StepCore::Class::staticMetaObject()); \
0069         _extMetaObjects.insert(StepCore::Class::staticMetaObject(), &extMetaObject ## Class); \
0070         _orderedMetaObjects.push_back(QString(StepCore::Class::staticMetaObject()->className())); \
0071         loadIcon(StepCore::Class::staticMetaObject(), const_cast<ExtMetaObject*>(&extMetaObject ## Class))
0072 
0073     #define ___REGISTER_EXT_E(Class, newGraphicsCreator, newGraphicsItem, newItemMenuHandler) \
0074         ___REGISTER_EXT(Class, newGraphicsCreator, newGraphicsItem, newItemMenuHandler); \
0075         registerMetaObject(StepCore::Class##Errors::staticMetaObject())
0076 
0077     #define __REGISTER(Class) ___REGISTER_EXT(Class, NULL, NULL, NULL)
0078     #define __REGISTER_E(Class) ___REGISTER_EXT_E(Class, NULL, NULL, NULL)
0079 
0080     #define __REGISTER_EXT(Class, GraphicsCreator, GraphicsItem, ItemMenuHandler) \
0081         ___REGISTER_EXT(Class, newItemCreatorHelper<GraphicsCreator>, \
0082                    newGraphicsItemHelper<GraphicsItem>, newItemMenuHandlerHelper<ItemMenuHandler>)
0083 
0084     #define __REGISTER_EXT_E(Class, GraphicsCreator, GraphicsItem, ItemMenuHandler) \
0085         __REGISTER_EXT(Class, GraphicsCreator, GraphicsItem, ItemMenuHandler); \
0086         registerMetaObject(StepCore::Class##Errors::staticMetaObject())
0087 
0088     #define __ADD_TO_PALETTE(Class) \
0089         _paletteMetaObjects.push_back(QString(StepCore::Class::staticMetaObject()->className()))
0090 
0091     #define __ADD_SEPARATOR \
0092         _paletteMetaObjects.push_back(QString())
0093 
0094     __REGISTER_E(Object);
0095 
0096     __REGISTER(Item);
0097     __REGISTER(World);
0098     __REGISTER(ItemGroup);
0099     __REGISTER(Body);
0100     __REGISTER(Force);
0101     __REGISTER(Solver);
0102     __REGISTER(CollisionSolver);
0103     __REGISTER(ConstraintSolver);
0104 
0105     __REGISTER_EXT_E(Particle, ItemCreator, ParticleGraphicsItem, ItemMenuHandler);
0106     __REGISTER_EXT_E(ChargedParticle, ItemCreator, ParticleGraphicsItem, ItemMenuHandler);
0107 
0108     __REGISTER_EXT(Disk, DiskCreator, DiskGraphicsItem, ItemMenuHandler);
0109     __REGISTER_EXT(Box, BoxCreator, BoxGraphicsItem, ItemMenuHandler);
0110     __REGISTER_EXT(Polygon, PolygonCreator, PolygonGraphicsItem, ItemMenuHandler);
0111 
0112     __REGISTER_EXT(GasParticle, ItemCreator, ParticleGraphicsItem, ItemMenuHandler);
0113     __REGISTER(GasLJForce);
0114     __REGISTER_EXT(Gas, GasCreator, GasGraphicsItem, GasMenuHandler);
0115 
0116     __REGISTER_EXT(SoftBodySpring, SpringCreator, SoftBodySpringGraphicsItem, ItemMenuHandler);
0117     __REGISTER_EXT(SoftBodyParticle, ItemCreator, SoftBodyParticleGraphicsItem, ItemMenuHandler);
0118     __REGISTER_EXT(SoftBody, SoftBodyCreator, SoftBodyGraphicsItem, SoftBodyMenuHandler);
0119 
0120     __REGISTER_EXT_E(Spring, SpringCreator, SpringGraphicsItem, ItemMenuHandler);
0121     __REGISTER_EXT(LinearMotor, LinearMotorCreator, LinearMotorGraphicsItem, ItemMenuHandler);
0122     __REGISTER_EXT(CircularMotor, CircularMotorCreator, CircularMotorGraphicsItem, ItemMenuHandler);
0123 
0124     __REGISTER_E(WeightForce);
0125     __REGISTER_E(GravitationForce);
0126     __REGISTER_E(CoulombForce);
0127 
0128     __REGISTER_EXT(Anchor, AnchorCreator, AnchorGraphicsItem, ItemMenuHandler);
0129     __REGISTER_EXT(Pin, PinCreator, PinGraphicsItem, ItemMenuHandler);
0130     __REGISTER_EXT(Stick, StickCreator, StickGraphicsItem, ItemMenuHandler);
0131     //__REGISTER_EXT(Rope, StickCreator, StickGraphicsItem, ItemMenuHandler);
0132 
0133     __REGISTER(EulerSolver);
0134     __REGISTER(AdaptiveEulerSolver);
0135 
0136     __REGISTER(GJKCollisionSolver);
0137     __REGISTER(CGConstraintSolver);
0138 
0139 #ifdef STEPCORE_WITH_GSL
0140     __REGISTER(GslRK2Solver);
0141     __REGISTER(GslRK4Solver);
0142     __REGISTER(GslRKF45Solver);
0143     __REGISTER(GslRKCKSolver);
0144     __REGISTER(GslRK8PDSolver);
0145     __REGISTER(GslRK2IMPSolver);
0146     __REGISTER(GslRK4IMPSolver);
0147 
0148     __REGISTER(GslAdaptiveRK2Solver);
0149     __REGISTER(GslAdaptiveRK4Solver);
0150     __REGISTER(GslAdaptiveRKF45Solver);
0151     __REGISTER(GslAdaptiveRKCKSolver);
0152     __REGISTER(GslAdaptiveRK8PDSolver);
0153     __REGISTER(GslAdaptiveRK2IMPSolver);
0154     __REGISTER(GslAdaptiveRK4IMPSolver);
0155 #endif
0156 
0157     __REGISTER(NoteImage);
0158     __REGISTER(NoteFormula);
0159     __REGISTER_EXT(Note, ItemCreator, NoteGraphicsItem, ItemMenuHandler);
0160     __REGISTER_EXT(Meter, ItemCreator, MeterGraphicsItem, MeterMenuHandler);
0161     __REGISTER_EXT(Graph, ItemCreator, GraphGraphicsItem, GraphMenuHandler);
0162     __REGISTER_EXT(Controller, ItemCreator, ControllerGraphicsItem, ControllerMenuHandler);
0163     __REGISTER_EXT(Tracer, TracerCreator, TracerGraphicsItem, TracerMenuHandler);
0164 
0165     // Palette
0166     __ADD_TO_PALETTE(Particle);
0167     __ADD_TO_PALETTE(ChargedParticle);
0168     __ADD_TO_PALETTE(Disk);
0169     __ADD_TO_PALETTE(Box);
0170     __ADD_TO_PALETTE(Polygon);
0171     __ADD_SEPARATOR;
0172 
0173     __ADD_TO_PALETTE(Spring);
0174     __ADD_TO_PALETTE(LinearMotor);
0175     __ADD_TO_PALETTE(CircularMotor);
0176     __ADD_SEPARATOR;
0177 
0178     __ADD_TO_PALETTE(Gas);
0179     __ADD_TO_PALETTE(SoftBody);
0180     __ADD_SEPARATOR;
0181 
0182     __ADD_TO_PALETTE(WeightForce);
0183     __ADD_TO_PALETTE(GravitationForce);
0184     __ADD_TO_PALETTE(CoulombForce);
0185     __ADD_SEPARATOR;
0186 
0187     __ADD_TO_PALETTE(Anchor);
0188     __ADD_TO_PALETTE(Pin);
0189     __ADD_TO_PALETTE(Stick);
0190     //__ADD_TO_PALETTE(Rope);
0191     __ADD_SEPARATOR;
0192 
0193     __ADD_TO_PALETTE(Note);
0194     __ADD_TO_PALETTE(Meter);
0195     __ADD_TO_PALETTE(Tracer);
0196     __ADD_TO_PALETTE(Graph);
0197     __ADD_TO_PALETTE(Controller);
0198 }
0199 
0200 WorldFactory::~WorldFactory()
0201 {
0202     delete _nullIcon; 
0203 }
0204 
0205 ItemCreator* WorldFactory::newItemCreator(const QString& className,
0206                     WorldModel* worldModel, WorldScene* worldScene) const
0207 {
0208     const StepCore::MetaObject* mObject = metaObject(className);
0209     if(!mObject) return nullptr;
0210     const ExtMetaObject *extMetaObject = _extMetaObjects.value(mObject, NULL);
0211     if(extMetaObject && extMetaObject->newItemCreator)
0212         return extMetaObject->newItemCreator(className, worldModel, worldScene);
0213     else return new ItemCreator(className, worldModel, worldScene);
0214 }
0215 
0216 StepGraphicsItem* WorldFactory::newGraphicsItem(StepCore::Item* item, WorldModel* worldModel) const
0217 {
0218     const ExtMetaObject *extMetaObject = _extMetaObjects.value(item->metaObject(), NULL);
0219     if(extMetaObject && extMetaObject->newGraphicsItem)
0220         return extMetaObject->newGraphicsItem(item, worldModel);
0221     return nullptr;
0222 }
0223 
0224 ItemMenuHandler* WorldFactory::newItemMenuHandler(StepCore::Object* object, WorldModel* worldModel, QObject* parent) const
0225 {
0226     const ExtMetaObject *extMetaObject = _extMetaObjects.value(object->metaObject(), NULL);
0227     if(extMetaObject && extMetaObject->newItemMenuHandler)
0228         return extMetaObject->newItemMenuHandler(object, worldModel, parent);
0229     else return new ItemMenuHandler(object, worldModel, parent);
0230 }
0231 
0232 bool WorldFactory::hasObjectIcon(const StepCore::MetaObject* mObject) const
0233 {
0234     const ExtMetaObject *extMetaObject = _extMetaObjects.value(mObject, NULL);
0235     if(extMetaObject && extMetaObject->hasIcon) return true;
0236     else return false;
0237 }
0238 
0239 const QIcon& WorldFactory::objectIcon(const StepCore::MetaObject* mObject) const
0240 {
0241     const ExtMetaObject *extMetaObject = _extMetaObjects.value(mObject, NULL);
0242     if (extMetaObject && extMetaObject->icon)
0243     return *(extMetaObject->icon);
0244     else {
0245         qWarning("Trying to load icon for unregistered metaObject\n");
0246         return *_nullIcon;
0247     }
0248 }
0249 
0250 void WorldFactory::loadIcon(const StepCore::MetaObject* metaObject, ExtMetaObject* extMetaObject)
0251 {
0252     QString iconName = QStringLiteral("step_object_") + metaObject->className();
0253     extMetaObject->icon = new QIcon(QIcon::fromTheme(iconName));
0254     QString iconPath = KIconLoader::global()->iconPath(iconName, KIconLoader::Small, true);
0255     extMetaObject->hasIcon = !iconPath.isEmpty();
0256 }
0257