Skip to content

Commit

Permalink
FEM: Add documentation for Fem::Constraint
Browse files Browse the repository at this point in the history
  • Loading branch information
Markus Hovorka authored and berndhahnebach committed Sep 21, 2019
1 parent 3b71a71 commit 88637ae
Showing 1 changed file with 188 additions and 23 deletions.
211 changes: 188 additions & 23 deletions src/Mod/Fem/App/FemConstraint.h
Expand Up @@ -30,50 +30,215 @@
#include <App/PropertyLinks.h>
#include <App/PropertyGeo.h>

namespace Fem
{

class AppFemExport Constraint : public App::DocumentObject
{
namespace Fem {

/**
* @brief Base class of all Constraint Objects of the Fem module.
*
* @details
* @ref Constraint isn't intended to be used directely. Actual Constraints
* used to specify a simulation are children of this class. The base class
* essentially does two things: Most importantely it has a property @ref
* Constraint::References which is a list of all sub objects the constraint
* applys to. Defining it in the base class exposes a common interface to code
* using different constraints.
*
* The second purpose of @ref Constraint is to support the redering to the
* screen done by the View Provider @ref FemGui::ViewProviderFemConstraint.
* The rendering is decoupled from the objects listed in the @ref References
* property by using a point cloud a normal vector and a scale factor which is
* generated by this class. The View Provider doesn't know of the references
* it just asks @ref Constraint for those values and renders a widget for each
* point scaled by the scale factor pointing in the direction of the normal
* vector. These values are exposed by the two properties @ref NormalDirection
* and @ref Scale and the protected method @ref getPoints(points&, normals&,
* scale&).
*/
class AppFemExport Constraint : public App::DocumentObject {
PROPERTY_HEADER(Fem::Constraint);

public:
/// Constructor
Constraint(void);
Constraint();
virtual ~Constraint();

/**
* @brief List of objects the constraints applies to.
*
* @details
* This is a list of subobjects (e.g. Faces, Edges, ...) the constraint
* applies to. It's only supposed to contain objects of or derived from
* Part::Feature. Altering this property triggers a update of @ref
* NormalDirection and @ref Scale.
*
* @note
* Undefined behaviour if a unsupported (not derived from Part::Feature)
* Document Object is added to the @References.
*/
App::PropertyLinkSubList References;
// Read-only (calculated values). These trigger changes in the ViewProvider

/**
* @brief Vector pointing into the effective direction of the constraint.
*
* @details
* If @ref References contains only one face of a shape than @ref
* NormalDirection is the normal vector of that face. If more than one
* face is referenced that it is the normal vector of the first face. If
* @ref References is empty or doesn't contain a face the value of @ref
* NormalDirection is the Z-axis or its previous value.
*/
App::PropertyVector NormalDirection;

//OvG: Scale
/**
* @brief Supposed to reflect the size of the @ref References.
*
* @details
* This property should be a scale factor for the widgets rendered by the
* View Provider but it's always 1. It isn't updated when @ref References
* changes.
*/
App::PropertyInteger Scale;

/// recalculate the object
virtual App::DocumentObjectExecReturn *execute(void);

/// returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemConstraint";
}

//OvG: Allow automatic determination of scaling of constraint drawings, e.g. arrow length and size
/**
* @brief Updates @ref NormalDirection.
*
* @details
* Updates @ref NormalDirection using new @ref References. It does so by
* calling @ref onChanged once with the @ref References property and once
* with the @ref Scale property. The second call doesn't do anything.
*
* @note
* Calling @ref onChanged does touch the Document Object but that flag is
* cleared right after the @ref execute call by the recompute mechanism.
* See Document::recompute() and DocumentObject::purgeTouched().
*/
virtual App::DocumentObjectExecReturn *execute();

/**
* @brief Calculates scale factor based on length of edge.
*
* @details
* Used to calculate the scale factor returned by @ref getPoints when the
* scale factor is calculated for a face.
*
* @note
* This method does a really crazy calculation that I didn't dare to try
* to understand.
*/
int calcDrawScaleFactor(double lparam) const;

/**
* @brief Calculates scale factor based on size of face.
*
* @details
* Used to calculate the scale factor returned by @ref getPoints when the
* scale factor is calculated for a edge.
*
* @note
* This method does a really crazy calculation that I didn't dare to try
* to understand.
*/
int calcDrawScaleFactor(double lvparam, double luparam) const;

/**
* @brief Returns default scale factor of 1.
*
* @details
* This is just used to make code more understandable. Other versions
* (overloads) of this function do useful calculations based on faces or
* edges. Used by @ref getPoints if no useful shape information is
* avaliable.
*
* @return always the integer 1
*/
int calcDrawScaleFactor() const;

virtual const char* getViewProviderName() const {
return "FemGui::ViewProviderFemConstraint";
}

protected:

/**
* @brief Updates NormalDirection if References change.
*/
virtual void onChanged(const App::Property* prop);

/**
* @brief Triggers @ref onChanged to update View Provider.
*
* @note
* This should not be nessesary and is properly a bug in the View Provider
* of FemConstraint.
*/
virtual void onDocumentRestored();

protected:
/// Calculate the points where symbols should be drawn
bool getPoints(std::vector<Base::Vector3d>& points, std::vector<Base::Vector3d>& normals, int * scale) const; //OvG: added scale parameter
bool getCylinder(double& radius, double& height, Base::Vector3d& base, Base::Vector3d& axis) const;
/**
* @brief Returns data based on References relevant for rendering widgets.
*
* @details
* Extracts data from all objects inside References relevant for widget
* rendering by the View Provider. This includes the points at which
* widgets shall be drawn, a vector per point indicating the direction the
* widget should face and a global scale factor for all widgets. Two
* vectors of equal length are used to return the points and their normal
* vectors. The normal vector of points[i] can be found with the same
* index in normals[i].
*
* @param[out] points
* For each vertex a point equal to the location of that vertix is pushed
* into the points vector. For each edge at least to points, the beginning
* and the end of the edge, are pushed into the vector. Depending on the
* length of the edge more points may be added in between. For each face a
* number of points depending on the size of the face and the step size
* calculated internally are pushed into the vector.
* @param[out] normals
* For vertexes and edges normal vectors equal to the NormalDirection are
* pushed onto the vector. For each point of a face a Base::Vector3d equal
* to the normal vector of the face at that position is added to the
* vector.
* @param[out] scale
* The scale contains a scale value for the object in References that was
* processed last. For calculation various versions of @ref
* calcDrawScaleFactor are used.
*
* @return
* If the calculation of points, normals and scale was successful it
* returns true. If an error occured and the data couldn't be extracted
* properly false is returned.
*/
bool getPoints(
std::vector<Base::Vector3d>& points,
std::vector<Base::Vector3d>& normals,
int * scale) const;

/**
* @brief Extract properties of cylindrical face.
*
* @note
* This method is very specific and doesn't requre access to member
* variables. It should be rewritten at a different palce.
*/
bool getCylinder(
double& radius, double& height,
Base::Vector3d& base, Base::Vector3d& axis) const;

/**
* @brief Calculate point of cylidrical face where to render widget.
*
* @note
* This method is very specific and doesn't requre access to member
* variables. It should be rewritten at a different palce.
*/
Base::Vector3d getBasePoint(const Base::Vector3d& base, const Base::Vector3d& axis,
const App::PropertyLinkSub &location, const double& dist);
/**
* @brief Get normal vector of point calculated by @ref getBasePoint.
*
* @note
* This method is very specific and doesn't requre access to member
* variables. It should be rewritten at a different palce.
*/
const Base::Vector3d getDirection(const App::PropertyLinkSub &direction);

};

typedef App::FeaturePythonT<Constraint> ConstraintPython;
Expand Down

0 comments on commit 88637ae

Please sign in to comment.