Tool to transform a 3D-model into scratches picture, that can be engraved onto semi-reflective material (vinil, aluminium) and used to show fake-hologram.
For more information check project wiki
Scratched hologram creation tool
Home Page: https://docs.google.com/document/d/19QneUm_1g40Md7sUHgH4ytLwdNjb5xF8KyYZEQd1-3M/edit?usp=sharing
License: GNU General Public License v3.0
Add new method:
void IVectorGraphicsDataWriter::writeMul(std::string filepath, const std::vector<CVectorGraphicsData> &data, bool write_force = false);
Writes several CVectorGraphicsData objects into one file
Method call example:
std::vector<CVectorGraphicsData> vec;
vec.emplace_back(someData1);
vec.emplace_back(someData2);
// ...
Writer w;
w.writeMul("some_path", vec);
CliTools::COption - immutable
CliTools::COptionBuilder
addShortName(char c)
addLongName(std::string)
addDescription(std::string)
setValued(bool has_value, bool option_required = false)
has_value - опция принимает значение, option_required - опция обязательная
buildOption() returns CliTools::COption throws EOptionBuildError
reset() - сбросить билдер к начальному значению
CliTools::CArgsParser
Exceptions:
CliTools::EOptionBuildError - исключение - билдер не получил достаточно аргументов
CliTools::EParserError - общий класс для исключений парсера
CliTools::ERequiredOptionNotPresent extends EParseError - обязательная опция не присутствует среди аргументов
CliTools::EValuedOptionWithoutValue extends EParseError - за опцией, принимающей значение, значение отсутствует
CliTools::EOptionNotPresentInDictionary extends EParseError - опция не найдена в словаре опций
App can be used with WebASM, which doesn't have good exception-handling mechanism. It'd be better to work with exception situations without throwing exceptions
Uses File3DProcessingTools, File2DProcessingTools, Geometry3D, Geometry2D libs
[Uses Geometry2D library]
// For now it's gonna be enough:
class CVectorGraphicsData {
public:
CVectorGraphicsData() = default;
CVectorGraphicsData(const CVectorGraphicsData &data) = default;
CVectorGraphicsData(CVectorGraphicsData &&data) = default;
CVectorGraphicsData &operator=(const CVectorGraphicsData &data) = default;
CVectorGraphicsData &operator=(CVectorGraphicsData &&data) = default;
void addLineSegment(CLineSegment2D) noexcept; // Store line segment [std::move() here]
const std::vector<CLineSegment2D>& getLineSegments() const noexcept; // Get all stored line
segments
};
Defines line object in 3D-space. Line linked to Geometry3D::AVector3D direction vector and Geometry3D::CPoint3D.
Определяет объект "линия" в трехмерном пространстве как совокупность направляющего вектора Geometry3D::AVector3D и точки Geometry3D::CPoint3D.
класс-перечесление с типом отношений между прямыми: (скрещиваются, параллельны, пересекаются, совпадают)
It's better to use const pointers.
class CLinkedLine3D {
private:
const AVector3D* p_direction_vector = nullprt;
const CPoint3D* p_linked_point = nullprt;
public:
enum class RelationType { SKEW, PARALLEL, CROSSING };
enum class CoordinateName { X, Y, Z };
CLinkedLine3D(const AVector3D& direction_vector, const CPoint3D& linked_point) noexcept;
void setDirectionVector(const AVector3D& direction_vector) noexcept;
void setLinkedPoint(const CPoint3D& linked_point) noexcept;
const AVector3D& getDirectionVector() const noexcept;
const CPoint3D& getLinkedPoint() const noexcept;
RelationType getRelationType(const CLinkedLine3D& line) const noexcept;
CPoint3D getCrossingPoint(const CLinkedLine3D& line) const noexcept;
bool isCrossesPoint(const CPoint3D& point) const noexcept;
double getLinePointX(double known_coordinate, CoordinateName known_coordinate_name) const noexcept;
double getLinePointY(double known_coordinate, CoordinateName known_coordinate_name) const noexcept;
double getLinePointZ(double known_coordinate, CoordinateName known_coordinate_name) const noexcept;
private:
// Leave with no definition
CLinkedLine3D(AVector3D&& direction_vector, CPoint3D&& linked_point) noexcept;
void setDirectionVector(AVector3D&& direction_vector) noexcept;
void setLinkedPoint(CPoint3D&& linked_point) noexcept;
};
NaN and INF example:
#include <iostream>
#include <cmath>
#include <limits>
int main() {
double nan_val = std::numeric_limits<double>::quiet_NaN();
double inf_val = std::numeric_limits<double>::infinity();
double normal_val = 3.9;
std::cout << nan_val << ' ' << std::isnormal(nan_val) << '\n';
std::cout << inf_val << ' ' << std::isnormal(inf_val) << '\n';
std::cout << normal_val << ' ' << std::isnormal(normal_val) << '\n';
}
Calculates distance between two points
double getDistance(const CPoint3D& point) const noexcept;
double getDistance(CPoint3D&& point) const noexcept;
void addLineSegments(Geometry2D::CLineSegment2D line_segment, unsigned int width_pixels = 1) noexcept;
void addLineSegments(InputIterator begin, InputIterator end, unsigned int width_pixels = 1) noexcept;
CColor_T
// Next color should be used for all next added objects
// Default is black
void setNextColor(CColor_T color) noexcept;
const std::vector<unsigned int> &getLineSegmentsWidths() const noexcept;
const std::vector<CColor_T> &getLineSegmentsColors() const noexcept;
// CPoint3D
void setX(double x) noexcept;
void setY(double x) noexcept;
void setZ(double x) noexcept;
// CVector3D
void setX(double x) noexcept;
void setY(double x) noexcept;
void setZ(double x) noexcept;
CVector3D& operator=(const CVector3D& vec) noexcept);
Default copy constructor produces incorrect copy of Edge's linked direction vectors, leaves its pointers to copied object vertexes
Add methods:
// Input data should be scaled to height
// Width should be recalculated by input data aspect ratio
virtual IVectorGraphicsDataWriter::setCanvasHeight(unsigned int height_px) noexcept;
// Input data should be scaled to width
// Height should be recalculated by input data aspect ratio
virtual IVectorGraphicsDataWriter::setCanvasWidth(unsigned int width_px) noexcept;
// Input data should be scaled to fit height and width
virtual IVectorGraphicsDataWriter::setCanvasSize(unsigned int height_px, unsigned int width_px) noexcept;
// Padding.first = vertical (up-side, down-side) padding width in pixels
// Padding.second = horizontal (left-side, right-side) padding width in pixels
// Rescale input data to fit if needed
virtual IVectorGraphicsDataWriter::setAlignmentCenter(std::pair<unsigned int, unsigned int> padding_зч = std::make_pair(0, 0)) noexcept;
Add operator==() for classes:
Classes:
Pack all the app functionality into command-line interface
Add methods:
void setPointBegin(const CPoint3D& new_point_begin) noexcept;
void setPointEnd(const CPoint3D& new_point_end) noexcept;
const CPoint3D& getPointBegin() const noexcept;
const CPoint3D& getPointBegin() const noexcept;
Note:
As references are not modifiable, to allow begin and end points changing, const pointers should be used. Such pointer declaration allows pointer changing, but not allows to change value.
Заметка:
Так как ссылки неименяемые, чтобы это реализовать, стоит перейти от хранения ссылок к хранению константных указателей. Такое декларирования указателя позволит менять сам указатель, но не значение, на которое он указывает
const CPoint3D *p_point_begin = nullptr;
const CPoint3D *p_point_end = nullptr;
// Assigning values
void setPointBegin(const CPoint3D& new_point_begin) noexcept {
p_point_begin = &new_point_begin;
}
Also it's forbidden to pass rvalue as set...() arguments. Make these methods private and leave them with no definition.
Также, необходимо запретить использовать rvalue как параметр set...() методов. Следует задекларировать соответствующие методы private и оставить без определения.
// Just declare with no definition
private:
void setPointBegin(CPoint3D&& new_point_begin) noexcept;
void setPointEnd(CPoint3D&& new_point_begin) noexcept;
Returns coordinate value of same-directed normalized vector
// Implement in AVector!
virtual double getNormalizedX() const noexcept;
virtual double getNormalizedY() const noexcept;
virtual double getNormalizedZ() const noexcept;
Model goes out of svg-canvas:
.\ScratchedHologramFrom3DApp.exe -i cube.obj -o cube.svg -d 100 -h 20 -a 50 -n 500 -x 0.1 -k 0.2 -s 0.7
Used default Blender cube model
fix setAligmentCenter(...): Does not center the image
Почекать идеи интерполяции кривой можно:
class CPath {
public:
CPath(); // Default width 1px, default color BLACK, smoth=false
CPath(unsigned int width_px, CColor color, bool smooth) noexcept;
void setColor(const CColor& color) noexcept; // цвет
CColor getColor() const noexcept;
void setWidth(unsigned int width_px) noexcept; // толщина в пикселях
unsigned int getWidth() const noexcept;
void setSmooth(bool flag) noexcept; // сглаживание, атрибут для обработки в дальнейшем
bool isSmooth() const noexcept;
// Добавляет следующую точку к линии
// Если линия имеет одну из координат NaN - разрыв в линии, распознается методом toSeparatedPaths()
void appendPoint(const CPoint2D& point) noexcept;
const std::vector<CPoint2D>& getPoints() const noexcept;
// Разбивает линию на несколько линий, разрыв определяется точкой с NaN-координатой или циклом
std::vector<CPath> toSeparatedPaths();
// Проверяет, зациклена ли кривая. Если да - отмечает, что есть цикл, чтоб не дублировать точку начала/конца при записи в файл
void updateCycled() noexcept;
bool isCycled() const noexcept;
};
[Uses Geometry2D library]
class IVectorGraphicsDataWriter {
public:
// [param] write_force
// - if true && file already exists, overwrite file
// - if false && file already exists, throw EFileAlreadyExistsException
// If file can't be overwritten force, throw EFileCannotBeOverwritten
void write(std::string filepath, const CVectorGraphicsData& data, bool write_force) = 0;
};
class CSvgDataWriter : public IVectorGraphicsDataWriter {
// Implements IVectorGraphicsDataWriter
// Writes data into *.svg file
// ...
};
class EFileAlreadyExistsException : public std::exception {
// Extends std::exception
// ...
};
class EFileCannotBeOverwritten : public std::exception {
// Extends std::exception
// ...
};
Typedefs:
Classes to implement:
Used Geometry3D lib;
typedef std::vector<Geometry3D::CPoint3D>::size_type f3d_v_size_t;
typedef std::vector<Geometry3D::CVector3D>::size_type f3d_n_size_t;
typedef std::pair<f3d_v_size_t, f3d_v_size_t> edge_map_key_t;
class CEdge {
private:
Geometry3D::CLinkedVector3D direction_vector;
Geometry3D::CLinkedLine3D direction_line;
public:
CEdge(const Geometry3D::CPoint3D& vertex_first, const Geometry3D::CPoint3D& vertex_second) const noexcept;
const Geometry3D::CLinkedLine3D& getDirectionLine() const noexcept;
const Geometry3D::CLinkedVector3D& getDirectionVector() const noexcept;
const CPoint3D& getFirstPoint() const noexcept;
const CPoint3D& getSecondPoint() const noexcept;
};
class CPolygon {
private:
std::vector<edge_map_key_t> edges_points_indexes;
f3d_n_size_t normal_index;
bool polygon_build = false;
public:
CPolygon(f3d_n_size_t _normal_index) noexcept;
void linkEdge(edge_map_key_t edge) noexcept;
void makeReadonly() noexcept;
const std::vector<edge_map_key_t>& getEdges() const noexcept;
f3d_n_size_t getNormalIndex() const noexcept;
double getEquationA() const noexcept;
double getEquationB() const noexcept;
double getEquationC() const noexcept;
double getEquationD() const noexcept;
};
class CObject3DData {
protected:
double max_x = 0.0;
double min_x = 0.0;
double max_y = 0.0;
double min_y = 0.0;
double max_z = 0.0;
double min_z = 0.0;
std::vector<Geometry3D::CPoint3D> vertxes;
std::unordered_map<edge_map_key_t, CEdge, f_pair_hash> edges;
std::vector<Geometry3D::CVector3D> polygons_normals;
std::vector<CPolygon> polygons;
public:
void addVertex(CPoint3D point) noexcept;
void addPolygonNormal(CVector3D normal) noexcept;
void addPolygon(CPolygon polygon) noexcept;
};
class IFile3DReader {
public:
virtual CObject3DData getData(const std::string& filename) = 0; // Throws an exception if file cannot be readed
};
class CObjFile3DReader : public IFile3DReader {
virtual CObject3DData getData(const std::string& filename); // Throws an exception if file cannot be readed
};
class EWrongFileFormat : public std::exception {
public:
EFWrongFileFormat() = default;
EFWrongFileFormat(std::string cause);
char *what() const noexcept override;
};
class CPoints3DStatistics {
public:
explicit CPoints3DStatistics(const std::vector<Geometry3D::CPoint3D> &point) noexcept;
double getMaxX() const noexcept;
double getMinX() const noexcept;
double getMaxY() const noexcept;
double getMinY() const noexcept;
double getMaxZ() const noexcept;
double getMinZ() const noexcept;
};
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.