Download src/App/ComplexGeoData.h from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 20.1 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/App/ComplexGeoData.h
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/App/ComplexGeoData.h
-
curl -L -o ComplexGeoData.h https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/App/ComplexGeoData.h
20.1 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /**************************************************************************** | |
| * * | |
| * Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> * | |
| * Copyright (c) 2022 Zheng, Lei <realthunder.dev@gmail.com> * | |
| * Copyright (c) 2023 FreeCAD Project Association * | |
| * * | |
| * This file is part of FreeCAD. * | |
| * * | |
| * FreeCAD is free software: you can redistribute it and/or modify it * | |
| * under the terms of the GNU Lesser General Public License as * | |
| * published by the Free Software Foundation, either version 2.1 of the * | |
| * License, or (at your option) any later version. * | |
| * * | |
| * FreeCAD 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 * | |
| * Lesser General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Lesser General Public * | |
| * License along with FreeCAD. If not, see * | |
| * <https://www.gnu.org/licenses/>. * | |
| * * | |
| ***************************************************************************/ | |
| namespace Base | |
| { | |
| class Placement; | |
| class Rotation; | |
| template<class _Precision> | |
| class BoundBox3; // NOLINT | |
| using BoundBox3d = BoundBox3<double>; | |
| } // namespace Base | |
| namespace Data | |
| { | |
| // struct MappedChildElements; | |
| /// Option for App::GeoFeature::searchElementCache() | |
| enum class SearchOption | |
| { | |
| /// Whether to compare shape geometry | |
| CheckGeometry = 1, | |
| SingleResult = 2, | |
| }; | |
| typedef Base::Flags<SearchOption> SearchOptions; | |
| /** Segments | |
| * Sub-element type of the ComplexGeoData type | |
| * It is used to split an object in further sub-parts. | |
| */ | |
| class AppExport Segment: public Base::BaseClass | |
| { | |
| TYPESYSTEM_HEADER_WITH_OVERRIDE(); // NOLINT | |
| public: | |
| ~Segment() override = default; | |
| virtual std::string getName() const = 0; | |
| }; | |
| enum ElementMapResetPolicy | |
| { | |
| AllowNoMap, | |
| ForceEmptyMap | |
| }; | |
| /** ComplexGeoData Object | |
| */ | |
| class AppExport ComplexGeoData: public Base::Persistence, public Base::Handled | |
| { | |
| TYPESYSTEM_HEADER_WITH_OVERRIDE(); // NOLINT | |
| public: | |
| struct Line | |
| { | |
| uint32_t I1; | |
| uint32_t I2; | |
| }; | |
| struct Facet | |
| { | |
| uint32_t I1; | |
| uint32_t I2; | |
| uint32_t I3; | |
| }; | |
| struct Domain | |
| { | |
| std::vector<Base::Vector3d> points; | |
| std::vector<Facet> facets; | |
| }; | |
| /// Constructor | |
| ComplexGeoData(); | |
| /// Destructor | |
| ~ComplexGeoData() override = default; | |
| /** @name Sub-element management */ | |
| //@{ | |
| /** Sub type list | |
| * List of different sub-element types | |
| * its NOT a list of the sub-elements itself | |
| */ | |
| virtual std::vector<const char*> getElementTypes() const = 0; | |
| virtual unsigned long countSubElements(const char* Type) const = 0; | |
| /// Returns a generic element type and index. The determined element type isn't | |
| /// necessarily supported by this geometry. | |
| static std::pair<std::string, unsigned long> getTypeAndIndex(const char* Name); | |
| /// get the sub-element by type and number | |
| virtual Segment* getSubElement(const char* Type, unsigned long) const = 0; | |
| /// get sub-element by combined name | |
| virtual Segment* getSubElementByName(const char* Name) const; | |
| /** Get lines from segment */ | |
| virtual void getLinesFromSubElement(const Segment*, | |
| std::vector<Base::Vector3d>& Points, | |
| std::vector<Line>& lines) const; | |
| /** Get faces from segment */ | |
| virtual void getFacesFromSubElement(const Segment*, | |
| std::vector<Base::Vector3d>& Points, | |
| std::vector<Base::Vector3d>& PointNormals, | |
| std::vector<Facet>& faces) const; | |
| //@} | |
| /** @name Placement control */ | |
| //@{ | |
| /** Applies an additional transformation to the current transformation. */ | |
| void applyTransform(const Base::Matrix4D& rclTrf); | |
| /** Applies an additional translation to the current transformation. */ | |
| void applyTranslation(const Base::Vector3d&); | |
| /** Applies an additional rotation to the current transformation. */ | |
| void applyRotation(const Base::Rotation&); | |
| /** Override the current transformation with a placement | |
| * using the setTransform() method. | |
| */ | |
| void setPlacement(const Base::Placement& rclPlacement); | |
| /** Return the current transformation as placement using | |
| * getTransform(). | |
| */ | |
| Base::Placement getPlacement() const; | |
| /** Override the current transformation with the new one. | |
| * This method has to be handled by the child classes. | |
| * the actual placement and matrix is not part of this class. | |
| */ | |
| virtual void setTransform(const Base::Matrix4D& rclTrf) = 0; | |
| /** Return the current matrix | |
| * This method has to be handled by the child classes. | |
| * the actual placement and matrix is not part of this class. | |
| */ | |
| virtual Base::Matrix4D getTransform() const = 0; | |
| //@} | |
| /** @name Modification */ | |
| //@{ | |
| /// Applies a transformation on the real geometric data type | |
| virtual void transformGeometry(const Base::Matrix4D& rclMat) = 0; | |
| //@} | |
| /** @name Getting basic geometric entities */ | |
| //@{ | |
| /// Get the standard accuracy to be used with getPoints, getLines or getFaces | |
| virtual double getAccuracy() const; | |
| /// Get the bound box | |
| virtual Base::BoundBox3d getBoundBox() const = 0; | |
| /** Get point from line object intersection */ | |
| virtual Base::Vector3d getPointFromLineIntersection(const Base::Vector3f& base, | |
| const Base::Vector3f& dir) const; | |
| /** Get points from object with given accuracy */ | |
| virtual void getPoints(std::vector<Base::Vector3d>& Points, | |
| std::vector<Base::Vector3d>& Normals, | |
| double Accuracy, | |
| uint16_t flags = 0) const; | |
| /** Get lines from object with given accuracy */ | |
| virtual void getLines(std::vector<Base::Vector3d>& Points, | |
| std::vector<Line>& lines, | |
| double Accuracy, | |
| uint16_t flags = 0) const; | |
| /** Get faces from object with given accuracy */ | |
| virtual void getFaces(std::vector<Base::Vector3d>& Points, | |
| std::vector<Facet>& faces, | |
| double Accuracy, | |
| uint16_t flags = 0) const; | |
| /** Get the center of gravity | |
| * If this method is implemented then true is returned and the center of gravity. | |
| * The default implementation only returns false. | |
| */ | |
| virtual bool getCenterOfGravity(Base::Vector3d& center) const; | |
| virtual std::optional<Base::Vector3d> centerOfGravity() const; | |
| //@} | |
| static const std::string& elementMapPrefix(); | |
| /** @name Element name mapping */ | |
| //@{ | |
| /** Get element indexed name | |
| * | |
| * @param name: the input name | |
| * @param sid: optional output of and App::StringID involved forming this mapped name | |
| * | |
| * @return Returns an indexed name. | |
| */ | |
| IndexedName getIndexedName(const MappedName& name, ElementIDRefs* sid = nullptr) const; | |
| /** Get element mapped name | |
| * | |
| * @param name: the input name | |
| * @param allowUnmapped: If the queried element is not mapped, then return | |
| * an empty name if \c allowUnmapped is false, or | |
| * else, return the indexed name. | |
| * @param sid: optional output of and App::StringID involved forming this mapped name | |
| * @return Returns the mapped name. | |
| */ | |
| MappedName getMappedName(const IndexedName& element, | |
| bool allowUnmapped = false, | |
| ElementIDRefs* sid = nullptr) const; | |
| /** Return a pair of indexed name and mapped name | |
| * | |
| * @param name: the input name. | |
| * @param sid: optional output of any App::StringID involved in forming | |
| * this mapped name | |
| * @param copy: if true, copy the name string, or else use it as constant | |
| * string, and caller must make sure the memory is not freed. | |
| * | |
| * @return Returns the MappedElement which contains both the indexed and | |
| * mapped name. | |
| * | |
| * This function guesses whether the input name is an indexed name or | |
| * mapped, and perform a lookup and return the names found. If the input | |
| * name contains only alphabets and underscore followed by optional digits, | |
| * it will be treated as indexed name. Or else, it will be treated as | |
| * mapped name. | |
| */ | |
| MappedElement | |
| getElementName(const char* name, ElementIDRefs* sid = nullptr, bool copy = false) const; | |
| /** Add a sub-element name mapping. | |
| * | |
| * @param element: the original \c Type + \c Index element name | |
| * @param name: the mapped sub-element name. May or may not start with | |
| * elementMapPrefix(). | |
| * @param sid: in case you use a hasher to hash the element name, pass in | |
| * the string id reference using this parameter. You can have more than one | |
| * string id associated with the same name. | |
| * @param overwrite: if true, it will overwrite existing names | |
| * | |
| * @return Returns the stored mapped element name. | |
| * | |
| * An element can have multiple mapped names. However, a name can only be | |
| * mapped to one element | |
| * | |
| * Note: the original proc was in the context of ComplexGeoData, which provided `Tag` access, | |
| * now you must pass in `long masterTag` explicitly. | |
| */ | |
| MappedName setElementName(const IndexedName& element, | |
| const MappedName& name, | |
| long masterTag, | |
| const ElementIDRefs* sid = nullptr, | |
| bool overwrite = false) | |
| { | |
| return _elementMap->setElementName(element, name, masterTag, sid, overwrite); | |
| } | |
| bool hasElementMap() const | |
| { | |
| return _elementMap != nullptr; | |
| } | |
| /** Get mapped element names | |
| * | |
| * @param element: original element name with \c Type + \c Index | |
| * @param needUnmapped: if true, return the original element name if no | |
| * mapping is found | |
| * | |
| * @return a list of mapped names of the give element along with their | |
| * associated string ID references | |
| */ | |
| std::vector<std::pair<MappedName, ElementIDRefs>> | |
| getElementMappedNames(const IndexedName& element, bool needUnmapped = false) const; | |
| /// Hash the child element map postfixes to shorten element name from hierarchical maps | |
| void hashChildMaps(); | |
| /// Check if there is child element map | |
| bool hasChildElementMap() const; | |
| /// Append the Tag (if and only if it is non zero) into the element map | |
| virtual void | |
| reTagElementMap(long tag, App::StringHasherRef hasher, const char* postfix = nullptr) | |
| { | |
| (void)tag; | |
| (void)hasher; | |
| (void)postfix; | |
| } | |
| // NOTE: getElementHistory is now in ElementMap | |
| long getElementHistory(const MappedName& name, | |
| MappedName* original = nullptr, | |
| std::vector<MappedName>* history = nullptr) const | |
| { | |
| if (_elementMap != nullptr) { | |
| return _elementMap->getElementHistory(name, Tag, original, history); | |
| } | |
| return 0; | |
| }; | |
| void setMappedChildElements(const std::vector<Data::ElementMap::MappedChildElements>& children); | |
| std::vector<Data::ElementMap::MappedChildElements> getMappedChildElements() const; | |
| char elementType(const Data::MappedName&) const; | |
| char elementType(const Data::IndexedName&) const; | |
| char elementType(const char* name) const; | |
| /** Reset/swap the element map | |
| * | |
| * @param elementMap: optional new element map | |
| * | |
| * @return Returns the existing element map. | |
| */ | |
| virtual ElementMapPtr resetElementMap(ElementMapPtr elementMap = ElementMapPtr()); | |
| /// Get the entire element map | |
| std::vector<MappedElement> getElementMap() const; | |
| /// Set the entire element map | |
| void setElementMap(const std::vector<MappedElement>& elements); | |
| /// Get the current element map size | |
| size_t getElementMapSize(bool flush = true) const; | |
| /// Return the higher level element names of the given element | |
| virtual std::vector<IndexedName> getHigherElements(const char* name, bool silent = false) const; | |
| /// Return the current element map version | |
| virtual std::string getElementMapVersion() const; | |
| /// Return true to signal element map version change | |
| virtual bool checkElementMapVersion(const char* ver) const; | |
| /// Check if the given sub-name only contains an element name | |
| static bool isElementName(const char* subName) | |
| { | |
| return (subName != nullptr) && (*subName != 0) && findElementName(subName) == subName; | |
| } | |
| /** Iterate through the history of the give element name with a given callback | |
| * | |
| * @param name: the input element name | |
| * @param cb: trace callback with call signature. | |
| * @sa TraceCallback | |
| */ | |
| void traceElement(const MappedName& name, TraceCallback cb) const | |
| { | |
| _elementMap->traceElement(name, Tag, std::move(cb)); | |
| } | |
| /** Flush an internal buffering for element mapping */ | |
| virtual void flushElementMap() const; | |
| //@} | |
| /** @name Save/restore */ | |
| //@{ | |
| void Save(Base::Writer& writer) const override; | |
| void Restore(Base::XMLReader& reader) override; | |
| void SaveDocFile(Base::Writer& writer) const override; | |
| void RestoreDocFile(Base::Reader& reader) override; | |
| unsigned int getMemSize() const override; | |
| void setPersistenceFileName(const char* name) const; | |
| virtual void beforeSave() const; | |
| bool isRestoreFailed() const | |
| { | |
| return _restoreFailed; | |
| } | |
| void resetRestoreFailure() const | |
| { | |
| _restoreFailed = true; | |
| } | |
| //@} | |
| /** | |
| * Debugging method to dump an entire element map in human readable form to a stream | |
| * @param stream | |
| */ | |
| void dumpElementMap(std::ostream& stream) const; | |
| /** | |
| * Debugging method to dump an entire element map in human readable form into a string | |
| * @return The string | |
| */ | |
| const std::string dumpElementMap() const; | |
| protected: | |
| /// from local to outside | |
| inline Base::Vector3d transformPointToOutside(const Base::Vector3f& vec) const | |
| { | |
| // clang-format off | |
| return getTransform() * Base::Vector3d(static_cast<double>(vec.x), | |
| static_cast<double>(vec.y), | |
| static_cast<double>(vec.z)); | |
| // clang-format on | |
| } | |
| /// from local to outside | |
| template<typename Vec> | |
| inline std::vector<Base::Vector3d> transformPointsToOutside(const std::vector<Vec>& input) const | |
| { | |
| // clang-format off | |
| std::vector<Base::Vector3d> output; | |
| output.reserve(input.size()); | |
| Base::Matrix4D mat(getTransform()); | |
| std::transform(input.cbegin(), input.cend(), std::back_inserter(output), | |
| [&mat](const Vec& vec) { | |
| return mat * Base::Vector3d(static_cast<double>(vec.x), | |
| static_cast<double>(vec.y), | |
| static_cast<double>(vec.z)); | |
| }); | |
| return output; | |
| // clang-format on | |
| } | |
| inline Base::Vector3d transformVectorToOutside(const Base::Vector3f& vec) const | |
| { | |
| // clang-format off | |
| Base::Matrix4D mat(getTransform()); | |
| mat.setCol(3, Base::Vector3d()); | |
| return mat * Base::Vector3d(static_cast<double>(vec.x), | |
| static_cast<double>(vec.y), | |
| static_cast<double>(vec.z)); | |
| // clang-format on | |
| } | |
| template<typename Vec> | |
| std::vector<Base::Vector3d> transformVectorsToOutside(const std::vector<Vec>& input) const | |
| { | |
| // clang-format off | |
| std::vector<Base::Vector3d> output; | |
| output.reserve(input.size()); | |
| Base::Matrix4D mat(getTransform()); | |
| mat.setCol(3, Base::Vector3d()); | |
| std::transform(input.cbegin(), input.cend(), std::back_inserter(output), | |
| [&mat](const Vec& vec) { | |
| return mat * Base::Vector3d(static_cast<double>(vec.x), | |
| static_cast<double>(vec.y), | |
| static_cast<double>(vec.z)); | |
| }); | |
| return output; | |
| // clang-format on | |
| } | |
| /// from local to inside | |
| inline Base::Vector3f transformPointToInside(const Base::Vector3d& vec) const | |
| { | |
| Base::Matrix4D tmpM(getTransform()); | |
| tmpM.inverse(); | |
| Base::Vector3d tmp = tmpM * vec; | |
| return Base::Vector3f(static_cast<float>(tmp.x), | |
| static_cast<float>(tmp.y), | |
| static_cast<float>(tmp.z)); | |
| } | |
| public: | |
| mutable long Tag {0}; | |
| /// String hasher for element name shortening | |
| mutable App::StringHasherRef Hasher; | |
| protected: | |
| void restoreStream(std::istream& stream, std::size_t count); | |
| void readElements(Base::XMLReader& reader, size_t count); | |
| /// from local to outside | |
| inline Base::Vector3d transformToOutside(const Base::Vector3f& vec) const | |
| { | |
| // clang-format off | |
| return getTransform() * Base::Vector3d(static_cast<double>(vec.x), | |
| static_cast<double>(vec.y), | |
| static_cast<double>(vec.z)); | |
| // clang-format on | |
| } | |
| /// from local to inside | |
| inline Base::Vector3f transformToInside(const Base::Vector3d& vec) const | |
| { | |
| Base::Matrix4D tmpM(getTransform()); | |
| tmpM.inverse(); | |
| Base::Vector3d tmp = tmpM * vec; | |
| return Base::Vector3f(static_cast<float>(tmp.x), | |
| static_cast<float>(tmp.y), | |
| static_cast<float>(tmp.z)); | |
| } | |
| protected: | |
| ElementMapPtr elementMap(bool flush = true) const; | |
| ElementMapPtr ensureElementMap(bool flush = true); | |
| private: | |
| ElementMapPtr _elementMap; | |
| protected: | |
| mutable std::string _persistenceName; | |
| mutable bool _restoreFailed = false; | |
| }; | |
| } // namespace Data | |
| ENABLE_BITMASK_OPERATORS(Data::SearchOption) | |