AbdulElahGwaith's picture
Upload folder using huggingface_hub
a5ffdcd verified
/****************************************************************************
**
** This file is part of the LibreCAD project, a 2D CAD program
**
** Copyright (C) 2015 A. Stebich (librecad@mail.lordofbikes.de)
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file gpl-2.0.txt included in the
** packaging of this file.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**
** This copyright notice MUST APPEAR in all copies of the script!
**
**********************************************************************/
#ifndef RS_ENTITY_H
#define RS_ENTITY_H
#include <QString>
#include "lc_drawable.h"
#include "rs_undoable.h"
#include "rs_vector.h"
class RS_Pen;
class RS_Line;
class RS_Layer;
class RS_Document;
class RS_Insert;
class RS_Block;
class RS_Graphic;
class RS_EntityContainer;
class LC_Quadratic;
/**
* Base class for an entity (line, arc, circle, ...)
*
* @author Andrew Mustun
*/
class RS_Entity:public RS_Undoable, public LC_Drawable {
public:
RS_Entity(RS_EntityContainer *parent = nullptr);
// RS_Entity(RS_EntityContainer *parent, bool setPenToActive = false);
RS_Entity(const RS_Entity& entity);
RS_Entity& operator = (const RS_Entity& entity);
RS_Entity(RS_Entity&& entity);
RS_Entity& operator = (RS_Entity&& entity);
~RS_Entity() override;
virtual RS_Entity *clone() const = 0;
virtual RS_Entity *cloneProxy() const;
virtual void reparent(RS_EntityContainer *parent){
this->parent = parent;
}
void resetBorders();
void moveBorders(const RS_Vector &offset);
void scaleBorders(const RS_Vector &center, const RS_Vector &factor);
/**
* Identify all entities as undoable entities.
* @return RS2::UndoableEntity
*/
RS2::UndoableType undoRtti() const override{
return RS2::UndoableEntity;
}
/**
* @return Unique Id of this entity.
*/
unsigned long long getId() const;
/**
* This method must be overwritten in subclasses and return the
* number of <b>atomic</b> entities in this entity.
*/
virtual unsigned int count() const = 0;
/**
* This method must be overwritten in subclasses and return the
* number of <b>atomic</b> entities in this entity including sub containers.
*/
virtual unsigned int countDeep() const = 0;
/**
* Implementations must return the total length of the entity
* or a negative number if the entity has no length (e.g. a text or hatch).
*/
virtual double getLength() const{
return -1.0;
}
/**
* @return Parent of this entity or nullptr if this is a root entity.
*/
RS_EntityContainer *getParent() const{
return parent;
}
/**
* Reparents this entity.
*/
void setParent(RS_EntityContainer *p){
parent = p;
}
/** @return The center point (x) of this arc */
//get center for entities arc, circle and ellipse
virtual RS_Vector getCenter() const;
virtual double getRadius() const;
virtual void setRadius(double r);
virtual RS_Graphic* getGraphic() const;
RS_Block *getBlock() const;
RS_Insert *getInsert() const;
RS_Entity *getBlockOrInsert() const;
RS_Document *getDocument() const;
void setLayer(const QString &name);
void setLayer(RS_Layer *l);
void setLayerToActive();
RS_Layer *getLayer(bool resolve = true) const;
RS_Layer *getLayerResolved() const;
/**
* Sets the explicit pen for this entity or a pen with special
* attributes such as BY_LAYER, ..
*/
void setPen(const RS_Pen &pen);
void setPenToActive();
RS_Pen getPen(bool resolve = true) const;
RS_Pen getPenResolved() const;
/**
* Must be overwritten to return true if an entity type
* is a container for other entities (e.g. polyline, group, ...).
*/
virtual bool isContainer() const = 0;
/**
* Must be overwritten to return true if an entity type
* is an atomic entity.
*/
virtual bool isAtomic() const = 0;
/**
* Must be overwritten to return true if an entity type
* is a potential edge entity of a contour. By default
* this returns false.
*/
virtual bool isEdge() const{
return false;
}
/**
* @return true for all document entities (e.g. Graphics or Blocks).
* false otherwise.
*/
virtual bool isDocument() const{
return false;
}
virtual bool setSelected(bool select);
virtual bool toggleSelected();
virtual bool isSelected() const;
bool isParentSelected() const;
virtual bool isProcessed() const;
virtual void setProcessed(bool on);
bool isInWindow(RS_Vector v1, RS_Vector v2) const;
virtual bool hasEndpointsWithinWindow(const RS_Vector & /*v1*/, const RS_Vector & /*v2*/) const {
return false;
}
virtual bool isVisible() const;
virtual void setVisible(bool v);
virtual void setHighlighted(bool on);
virtual bool isHighlighted() const;
bool isTransparent() const;
void setTransparent(bool on);
bool isLocked() const;
void undoStateChanged(bool undone) override;
virtual bool isUndone() const;
/**
* Can be implemented by child classes to update the entities
* temporary subentities. update() is called if the entity's
* parameters or undo state changed.
*/
virtual void update(){}
virtual void setUpdateEnabled(bool on){
updateEnabled = on;
}
/**
* This method doesn't do any calculations.
* @return minimum coordinate of the entity.
* @see calculateBorders()
*/
RS_Vector getMin() const{
return minV;
}
/**
* This method doesn't do any calculations.
* @return minimum coordinate of the entity.
* @see calculateBorders()
*/
RS_Vector getMax() const{
return maxV;
}
/**
* This method returns the difference of max and min returned
* by the above functions.
* @return size of the entity.
* @see calculateBorders()
* @see getMin()
* @see getMax()
*/
RS_Vector getSize() const;
void addGraphicVariable(const QString &key, double val, int code);
void addGraphicVariable(const QString &key, int val, int code);
void addGraphicVariable(const QString &key, const QString &val, int code);
double getGraphicVariableDouble(const QString &key, double def);
int getGraphicVariableInt(const QString &key, int def) const;
QString getGraphicVariableString(
const QString &key,
const QString &def) const;
virtual RS_Vector getStartpoint() const;
virtual RS_Vector getEndpoint() const;
//find the local direction at end points, derived entities
// must implement this if direction is supported by the entity type
virtual double getDirection1() const{
return 0.;
}
virtual double getDirection2() const{
return 0.;
}
//find the tangential points seeing from given point
virtual RS_VectorSolutions getTangentPoint(const RS_Vector & /*point*/) const;
virtual RS_Vector getTangentDirection(const RS_Vector & /*point*/) const;
RS2::Unit getGraphicUnit() const;
/**
* Must be overwritten to get all reference points of the entity.
*/
virtual RS_VectorSolutions getRefPoints() const;
/**
* Must be overwritten to get the closest endpoint to the
* given coordinate for this entity.
*
* @param coord Coordinate (typically a mouse coordinate)
* @param dist Pointer to a value which will contain the measured
* distance between 'coord' and the closest endpoint. The passed
* pointer can also be nullptr in which case the distance will be
* lost.
*
* @return The closest endpoint.
*/
virtual RS_Vector getNearestEndpoint(
const RS_Vector &coord,
double *dist = nullptr) const = 0;
/**
* Must be overwritten to get the closest coordinate to the
* given coordinate which is on this entity.
*
* @param coord Coordinate (typically a mouse coordinate)
* @param dist Pointer to a value which will contain the measured
* distance between \p coord and the point. The passed pointer can
* also be \p nullptr in which case the distance will be lost.
*
* @return The closest coordinate.
*/
virtual RS_Vector getNearestPointOnEntity(
const RS_Vector & /*coord*/,
bool onEntity = true, double *dist = nullptr,
RS_Entity **entity = nullptr) const = 0;
/**
* Must be overwritten to get the (nearest) center point to the
* given coordinate for this entity.
*
* @param coord Coordinate (typically a mouse coordinate)
* @param dist Pointer to a value which will contain the measured
* distance between 'coord' and the closest center point. The passed
* pointer can also be nullptr in which case the distance will be
* lost.
*
* @return The closest center point.
*/
virtual RS_Vector getNearestCenter(
const RS_Vector &coord,
double *dist = nullptr) const = 0;
/**
* Must be overwritten to get the (nearest) middle point to the
* given coordinate for this entity.
*
* @param coord Coordinate (typically a mouse coordinate)
* @param dist Pointer to a value which will contain the measured
* distance between 'coord' and the closest middle point. The passed
* pointer can also be nullptr in which case the distance will be
* lost.
*
* @return The closest middle point.
*/
virtual RS_Vector getMiddlePoint(void) const{
return RS_Vector(false);
}
virtual RS_Vector getNearestMiddle(
const RS_Vector &coord,
double *dist = nullptr,
int middlePoints = 1
) const = 0;
/**
* Must be overwritten to get the nearest point with a given
* distance to the endpoint to the given coordinate for this entity.
*
* @param distance Distance to endpoint.
* @param coord Coordinate (typically a mouse coordinate)
* @param dist Pointer to a value which will contain the measured
* distance between 'coord' and the closest point. The passed
* pointer can also be nullptr in which case the distance will be
* lost.
*
* @return The closest point with the given distance to the endpoint.
*/
virtual RS_Vector getNearestDist(
double distance,
const RS_Vector &coord,
double *dist = nullptr) const = 0;
/**
* Must be overwritten to get the point with a given
* distance to the start- or endpoint to the given coordinate for this entity.
*
* @param distance Distance to endpoint.
* @param startp true = measured from Startpoint, false = measured from Endpoint
*
* @return The point with the given distance to the start- or endpoint.
*/
virtual RS_Vector getNearestDist(
double /*distance*/,
bool /*startp*/) const{
return RS_Vector(false);
}
/**
* @brief dualLineTangentPoint find the tangent point for a line in line coordinates
* @param line a tangent line in line coordinates
* @return the tangent point for the line
*/
virtual RS_Vector dualLineTangentPoint([[maybe_unused]] const RS_Vector &line) const{
return RS_Vector{false};
}
/**
* Must be overwritten to get the nearest reference point for this entity.
*
* @param coord Coordinate (typically a mouse coordinate)
* @param dist Pointer to a value which will contain the measured
* distance between 'coord' and the closest point. The passed
* pointer can also be nullptr in which case the distance will be
* lost.
*
* @return The closest point with the given distance to the endpoint.
*/
virtual RS_Vector getNearestRef(
const RS_Vector &coord,
double *dist = nullptr) const;
/**
* Gets the nearest reference point of this entity if it is selected.
* Containers re-implement this method to return the nearest reference
* point of a selected sub entity.
*
* @param coord Coordinate (typically a mouse coordinate)
* @param dist Pointer to a value which will contain the measured
* distance between 'coord' and the closest point. The passed
* pointer can also be nullptr in which case the distance will be
* lost.
*
* @return The closest point with the given distance to the endpoint.
*/
virtual RS_Vector getNearestSelectedRef(
const RS_Vector &coord,
double *dist = nullptr) const;
/**
* Must be overwritten to get the shortest distance between this
* entity and a coordinate.
*
* @param coord Coordinate (typically a mouse coordinate)
* @param entity Pointer which will contain the (sub-)entity which is
* closest to the given point or nullptr if the caller is not
* interested in this information.
* @param level The resolve level.
*
* @sa RS2::ResolveLevel
*
* @return The measured distance between \p coord and the entity.
*/
virtual RS_Vector getNearestOrthTan(
const RS_Vector & /*coord*/,
const RS_Line & /*normal*/,
bool onEntity = false) const;
virtual double getDistanceToPoint(
const RS_Vector &coord,
RS_Entity **entity = nullptr,
RS2::ResolveLevel level = RS2::ResolveNone,
double solidDist = RS_MAXDOUBLE) const;
virtual bool isPointOnEntity(
const RS_Vector &coord,
double tolerance = 20. * RS_TOLERANCE) const;
/**
* Implementations must offset the entity by the given direction and distance.
*/
virtual bool offset(const RS_Vector & /*coord*/, const double & /*distance*/){return false;}
/**
* Implementations must offset the entity by the distance at both directions
* used to generate tangential circles
*/
virtual std::vector<RS_Entity *> offsetTwoSides(const double & /*distance*/) const{
return std::vector<RS_Entity *>();
}
/**
* implementations must revert the direction of an atomic entity
*/
virtual void revertDirection(){}
/**
* Implementations must move the entity by the given vector.
*/
virtual void move(const RS_Vector &offset) = 0;
/**
* Implementations must rotate the entity by the given angle around
* the given center.
*/
virtual void rotate(const RS_Vector &center, double angle) = 0;
virtual void rotate(const RS_Vector &center, const RS_Vector &angleVector) = 0;
/**
* Implementations must scale the entity by the given factors.
*/
virtual void scale(const RS_Vector &center, const RS_Vector &factor) = 0;
/**
* Acts like scale(RS_Vector) but with equal factors.
* Equal to scale(center, RS_Vector(factor, factor)).
*/
virtual void scale(const RS_Vector &center, const double &factor){
scale(center, RS_Vector(factor, factor));
}
virtual void scale(const RS_Vector &factor){
scale(RS_Vector(0., 0.), factor);
}
/**
* Implementations must mirror the entity by the given axis.
*/
virtual void mirror(const RS_Vector &axisPoint1, const RS_Vector &axisPoint2) = 0;
virtual void stretch(
const RS_Vector &firstCorner,
const RS_Vector &secondCorner,
const RS_Vector &offset);
/**
* @description: Implementation of the Shear/Skew the entity
* The shear transform is
* 1 k 0
* 0 1 0
* 1
* @author Dongxu Li
* @param[in] double - k the skew/shear parameter
*/
virtual RS_Entity &shear(double k) = 0;
/**
* @description: Implementation of the Shear/Skew the entity
* The shear transform is
* 1 k 0
* 0 1 0
* 1
* @author Dongxu Li
* @param[in] const RS_Vector& - origin the point to be used as the origin
* @param[in] const RS_Vector& - the x-axis direction
* @param[in] double - k the skew/shear parameter
*/
virtual RS_Entity &shear(const RS_Vector &origin, const RS_Vector &xAxis, double k){
rotate(origin, -xAxis.angle());
move(-origin);
shear(k);
move(origin);
rotate(origin, xAxis.angle());
return *this;
}
/**
* Implementations must drag the reference point(s) of all
* (sub-)entities that are very close to ref by offset.
*/
virtual void moveRef(
const RS_Vector & /*ref*/,
const RS_Vector & /*offset*/){
return;
}
/**
* Implementations must drag the reference point(s) of selected
* (sub-)entities that are very close to ref by offset.
*/
virtual void moveSelectedRef(
const RS_Vector & /*ref*/,
const RS_Vector & /*offset*/){
return;
}
virtual void drawAsChild(RS_Painter *painter){
draw(painter);
}
virtual void drawDraft(RS_Painter *painter) {
draw(painter);
};
// double getStyleFactor(RS_GraphicView *view);
QString getUserDefVar(const QString &key) const;
std::vector<QString> getAllKeys() const;
void setUserDefVar(QString key, QString val);
void delUserDefVar(QString key);
friend std::ostream &operator<<(std::ostream &os, RS_Entity &e);
/** Recalculates the borders of this entity. */
virtual void calculateBorders() = 0;
/** whether the entity is on a constructionLayer */
//! constructionLayer contains entities of infinite length, constructionLayer doesn't show up in print
bool isConstruction(bool typeCheck = false) const; // ignore certain entity types for constructionLayer check
//! whether printing is enabled or disabled for the entity's layer
bool isPrint(void) const;
/** return the equation of the entity
for quadratic,
return a vector contains:
m0 x^2 + m1 xy + m2 y^2 + m3 x + m4 y + m5 =0
for linear:
m0 x + m1 y + m2 =0
**/
virtual LC_Quadratic getQuadratic() const;
/**
* @brief areaLineIntegral, line integral for contour area calculation by Green's Theorem
* Contour Area =\oint x dy
* @return line integral \oint x dy along the entity
*/
virtual double areaLineIntegral() const;
/**
* @brief trimmable, whether the entity type can be trimmed
* @return true, for trimmable entity types
* currently, trimmable types are: RS_Line, RS_Circle, RS_Arc, RS_Ellipse
*/
bool trimmable() const;
/**
* @brief isArc is the entity of type Arc, Circle, or Ellipse
* @return true for Arc, Circle, or Ellipse
*/
virtual bool isArc() const;
/**
* @brief isArcLine determine the entity is either Arc, Circle, or Line
* @return true if entity is Arc, Circle, or Line
*/
virtual bool isArcCircleLine() const;
bool isParentIgnoredOnModifications() const;
protected:
//! Entity's parent entity or nullptr is this entity has no parent.
RS_EntityContainer *parent = nullptr;
//! minimum coordinates
RS_Vector minV;
//! maximum coordinates
RS_Vector maxV;
//! Pointer to layer
RS_Layer *m_layer = nullptr;
//! auto updating enabled?
bool updateEnabled = false;
void init(bool setPenAndLayerToActive);
void initId();
private:
//! Entity m_id
unsigned long long m_id = 0;
// pImp to delay pulling in Qt headers
struct Impl;
std::unique_ptr<Impl> m_pImpl;
};
#endif