mirror of
https://github.com/leozide/leocad
synced 2024-11-17 07:47:55 +01:00
Synthesis of Technic Universal Joints (#456)
* Split synth info initialzation by type. We are going to remove the type enumeration and use a class hierarchy instead. This preparation will then be helpful. * Make Add...Parts() overrides of a virtual AddPart() function. Since we have a class hierarchy for the different synthesized pieces, we can now turn a case distinction into a virtual function call. * Move initialization based on type to derived class constructors. Move initialization of end transformations of flexible parts into class lcSynthInfoCurved. * Make GetDefaultControlPoints() virtual with overrides. * Remove obsolete enum lcSynthType. We have replaced its purpose by derived classes by now. * Initialize shock absorbers' spring part ID early. This removes the awkward early return that is needed in the if-else cascade. * Split lcSynthInfo into derived classes for curved and straight pieces. * Only curved parts have varying sections, start, middle, and end properties. Move the properties from the base class to the derived class that needs them. * Use derived classes to mark synthesized objects of different kinds. We will extend the derived classes in the upcoming commits. * PieceInfo is only needed to synthesize some hoses and shock absorbers. * Initialize edge part IDs of flexible hoses early. This removes another case distinction in AddParts(). * Verify the number of control points loaded from a model file. * Synthesize Technic universal joints. The direction of one end can be changed so that it points to the control point. * Technic universal joints need only the position of the control point. * Synthesize legacy universal joints.
This commit is contained in:
parent
b9662dd3e0
commit
ca73f3e3ad
5 changed files with 729 additions and 365 deletions
|
@ -684,6 +684,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||||
Piece->SetPieceInfo(Info, PartId, false);
|
Piece->SetPieceInfo(Info, PartId, false);
|
||||||
Piece->Initialize(Transform, CurrentStep);
|
Piece->Initialize(Transform, CurrentStep);
|
||||||
Piece->SetColorCode(ColorCode);
|
Piece->SetColorCode(ColorCode);
|
||||||
|
Piece->VerifyControlPoints(ControlPoints);
|
||||||
Piece->SetControlPoints(ControlPoints);
|
Piece->SetControlPoints(ControlPoints);
|
||||||
AddPiece(Piece);
|
AddPiece(Piece);
|
||||||
Piece = nullptr;
|
Piece = nullptr;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,29 +3,13 @@
|
||||||
#include "lc_math.h"
|
#include "lc_math.h"
|
||||||
#include "piece.h"
|
#include "piece.h"
|
||||||
|
|
||||||
enum class lcSynthType
|
|
||||||
{
|
|
||||||
HOSE_FLEXIBLE,
|
|
||||||
FLEX_SYSTEM_HOSE,
|
|
||||||
RIBBED_HOSE,
|
|
||||||
FLEXIBLE_AXLE,
|
|
||||||
STRING_BRAIDED,
|
|
||||||
SHOCK_ABSORBER,
|
|
||||||
ACTUATOR
|
|
||||||
};
|
|
||||||
|
|
||||||
struct lcSynthComponent
|
|
||||||
{
|
|
||||||
lcMatrix44 Transform;
|
|
||||||
float Length;
|
|
||||||
};
|
|
||||||
|
|
||||||
class lcLibraryMeshData;
|
class lcLibraryMeshData;
|
||||||
|
|
||||||
class lcSynthInfo
|
class lcSynthInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
lcSynthInfo(lcSynthType Type, float Length, int NumSections, PieceInfo* Info);
|
explicit lcSynthInfo(float Length);
|
||||||
|
virtual ~lcSynthInfo() = default;
|
||||||
|
|
||||||
bool CanAddControlPoints() const
|
bool CanAddControlPoints() const
|
||||||
{
|
{
|
||||||
|
@ -37,33 +21,30 @@ public:
|
||||||
return mCurve;
|
return mCurve;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetDefaultControlPoints(lcArray<lcPieceControlPoint>& ControlPoints) const;
|
bool IsUnidirectional() const
|
||||||
|
{
|
||||||
|
return mUnidirectional;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsNondirectional() const
|
||||||
|
{
|
||||||
|
return mNondirectional;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void GetDefaultControlPoints(lcArray<lcPieceControlPoint>& ControlPoints) const = 0;
|
||||||
|
virtual void VerifyControlPoints(lcArray<lcPieceControlPoint>& ControlPoints) const = 0;
|
||||||
int InsertControlPoint(lcArray<lcPieceControlPoint>& ControlPoints, const lcVector3& Start, const lcVector3& End) const;
|
int InsertControlPoint(lcArray<lcPieceControlPoint>& ControlPoints, const lcVector3& Start, const lcVector3& End) const;
|
||||||
lcMesh* CreateMesh(const lcArray<lcPieceControlPoint>& ControlPoints) const;
|
lcMesh* CreateMesh(const lcArray<lcPieceControlPoint>& ControlPoints) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float GetSectionTwist(const lcMatrix44& StartTransform, const lcMatrix44& EndTransform) const;
|
|
||||||
using SectionCallbackFunc = std::function<void(const lcVector3& CurvePoint, int SegmentIndex, float t)>;
|
using SectionCallbackFunc = std::function<void(const lcVector3& CurvePoint, int SegmentIndex, float t)>;
|
||||||
void CalculateCurveSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, SectionCallbackFunc SectionCallback) const;
|
virtual void CalculateSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, SectionCallbackFunc SectionCallback) const = 0;
|
||||||
void CalculateLineSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, SectionCallbackFunc SectionCallback) const;
|
virtual void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray<lcMatrix44>& Sections) const = 0;
|
||||||
void AddHoseFlexibleParts(lcMemFile& File, const lcArray<lcMatrix44>& Sections) const;
|
|
||||||
void AddFlexHoseParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray<lcMatrix44>& Sections) const;
|
|
||||||
void AddRibbedHoseParts(lcMemFile& File, const lcArray<lcMatrix44>& Sections) const;
|
|
||||||
void AddFlexibleAxleParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray<lcMatrix44>& Sections) const;
|
|
||||||
void AddStringBraidedParts(lcMemFile& File, lcLibraryMeshData& MeshData, lcArray<lcMatrix44>& Sections) const;
|
|
||||||
void AddShockAbsorberParts(lcMemFile& File, lcArray<lcMatrix44>& Sections) const;
|
|
||||||
void AddActuatorParts(lcMemFile& File, lcArray<lcMatrix44>& Sections) const;
|
|
||||||
|
|
||||||
PieceInfo* mPieceInfo;
|
bool mCurve = false;
|
||||||
lcSynthType mType;
|
bool mUnidirectional = false;
|
||||||
lcSynthComponent mStart;
|
bool mNondirectional = false;
|
||||||
lcSynthComponent mMiddle;
|
|
||||||
lcSynthComponent mEnd;
|
|
||||||
bool mCurve;
|
|
||||||
float mLength;
|
float mLength;
|
||||||
float mCenterLength;
|
|
||||||
int mNumSections;
|
|
||||||
bool mRigidEdges;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void lcSynthInit();
|
void lcSynthInit();
|
||||||
|
|
|
@ -797,19 +797,27 @@ void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix)
|
||||||
|
|
||||||
quint32 lcPiece::GetAllowedTransforms() const
|
quint32 lcPiece::GetAllowedTransforms() const
|
||||||
{
|
{
|
||||||
|
const quint32 Move = LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
|
||||||
|
const quint32 Rotate = LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
|
||||||
quint32 Section = GetFocusSection();
|
quint32 Section = GetFocusSection();
|
||||||
|
|
||||||
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
|
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
|
||||||
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
|
return Move | Rotate;
|
||||||
|
|
||||||
lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo();
|
lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo();
|
||||||
if (!SynthInfo)
|
if (SynthInfo)
|
||||||
return 0;
|
{
|
||||||
|
if (SynthInfo->IsUnidirectional())
|
||||||
|
return LC_OBJECT_TRANSFORM_MOVE_Z;
|
||||||
|
|
||||||
if (SynthInfo->IsCurve())
|
if (SynthInfo->IsCurve())
|
||||||
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z | LC_OBJECT_TRANSFORM_SCALE_X;
|
return Move | Rotate | LC_OBJECT_TRANSFORM_SCALE_X;
|
||||||
else
|
|
||||||
return LC_OBJECT_TRANSFORM_MOVE_Z;
|
if (SynthInfo->IsNondirectional())
|
||||||
|
return Move;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lcPiece::CanAddControlPoint() const
|
bool lcPiece::CanAddControlPoint() const
|
||||||
|
@ -866,6 +874,22 @@ bool lcPiece::RemoveFocusedControlPoint()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcPiece::VerifyControlPoints(lcArray<lcPieceControlPoint>& ControlPoints) const
|
||||||
|
{
|
||||||
|
lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo();
|
||||||
|
if (!SynthInfo)
|
||||||
|
{
|
||||||
|
ControlPoints.RemoveAll();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ControlPoints.GetSize() > LC_MAX_CONTROL_POINTS)
|
||||||
|
ControlPoints.SetSize(LC_MAX_CONTROL_POINTS);
|
||||||
|
|
||||||
|
SynthInfo->VerifyControlPoints(ControlPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* lcPiece::GetName() const
|
const char* lcPiece::GetName() const
|
||||||
{
|
{
|
||||||
return mPieceInfo->m_strDescription;
|
return mPieceInfo->m_strDescription;
|
||||||
|
|
|
@ -430,13 +430,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetControlPoints(const lcArray<lcPieceControlPoint>& ControlPoints)
|
void SetControlPoints(const lcArray<lcPieceControlPoint>& ControlPoints)
|
||||||
{
|
|
||||||
if (ControlPoints.GetSize() > 1)
|
|
||||||
{
|
{
|
||||||
mControlPoints = ControlPoints;
|
mControlPoints = ControlPoints;
|
||||||
UpdateMesh();
|
UpdateMesh();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SetControlPointScale(int ControlPointIndex, float Scale)
|
void SetControlPointScale(int ControlPointIndex, float Scale)
|
||||||
{
|
{
|
||||||
|
@ -472,6 +469,7 @@ public:
|
||||||
|
|
||||||
bool InsertControlPoint(const lcVector3& WorldStart, const lcVector3& WorldEnd);
|
bool InsertControlPoint(const lcVector3& WorldStart, const lcVector3& WorldEnd);
|
||||||
bool RemoveFocusedControlPoint();
|
bool RemoveFocusedControlPoint();
|
||||||
|
void VerifyControlPoints(lcArray<lcPieceControlPoint>& ControlPoints) const;
|
||||||
|
|
||||||
lcGroup* GetTopGroup();
|
lcGroup* GetTopGroup();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue