Implement an image request.
parent
e2e74762f4
commit
5744d1d599
|
@ -12,6 +12,7 @@ New sketch features:
|
|||
* A new sketch in workplane group can be created based on existing workplane.
|
||||
* TTF text request has two additional points on the right side, which allow
|
||||
constraining the width of text.
|
||||
* Image requests can now be created, similar to TTF text requests.
|
||||
* Irrelevant points (e.g. arc center point) are not counted when estimating
|
||||
the bounding box used to compute chord tolerance.
|
||||
* When adding a constraint which has a label and is redundant with another
|
||||
|
|
|
@ -158,6 +158,7 @@ add_resources(
|
|||
icons/graphics-window/equal.png
|
||||
icons/graphics-window/extrude.png
|
||||
icons/graphics-window/horiz.png
|
||||
icons/graphics-window/image.png
|
||||
icons/graphics-window/in3d.png
|
||||
icons/graphics-window/lathe.png
|
||||
icons/graphics-window/length.png
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
|
@ -4,7 +4,9 @@
|
|||
// Copyright 2016 Aleksey Egorov
|
||||
//-----------------------------------------------------------------------------
|
||||
uniform vec4 color;
|
||||
uniform sampler2D texture;
|
||||
|
||||
void main() {
|
||||
if(texture2D(texture, gl_FragCoord.xy / 32.0).a < 0.5) discard;
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
|
|
@ -195,6 +195,16 @@ void TextWindow::DescribeSelection() {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case Entity::Type::IMAGE: {
|
||||
Printf(false, "%FtIMAGE%E");
|
||||
Platform::Path relativePath = e->file.RelativeTo(SS.saveFile.Parent());
|
||||
if(relativePath.IsEmpty()) {
|
||||
Printf(true, " file = '%Fi%s%E'", e->file.raw.c_str());
|
||||
} else {
|
||||
Printf(true, " file = '%Fi%s%E'", relativePath.raw.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Printf(true, "%Ft?? ENTITY%E");
|
||||
|
|
|
@ -394,6 +394,9 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
|
|||
for(Entity &e : SK.entity) {
|
||||
if(!e.IsVisible()) continue;
|
||||
|
||||
// If faces aren't selectable, image entities aren't either.
|
||||
if(e.type == Entity::Type::IMAGE && !showFaces) continue;
|
||||
|
||||
// Don't hover whatever's being dragged.
|
||||
if(IsFromPending(e.h.request())) {
|
||||
// The one exception is when we're creating a new cubic; we
|
||||
|
|
|
@ -104,6 +104,7 @@ void Entity::GetReferencePoints(std::vector<Vector> *refs) {
|
|||
case Type::CUBIC:
|
||||
case Type::CUBIC_PERIODIC:
|
||||
case Type::TTF_TEXT:
|
||||
case Type::IMAGE:
|
||||
refs->push_back(SK.GetEntity(point[0])->PointGetNum());
|
||||
break;
|
||||
|
||||
|
@ -695,6 +696,54 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
case Type::IMAGE: {
|
||||
Canvas::Fill fill = {};
|
||||
std::shared_ptr<Pixmap> pixmap;
|
||||
switch(how) {
|
||||
case DrawAs::HIDDEN: return;
|
||||
|
||||
case DrawAs::HOVERED: {
|
||||
fill.color = Style::Color(Style::HOVERED).WithAlpha(180);
|
||||
fill.pattern = Canvas::FillPattern::CHECKERED_A;
|
||||
fill.zIndex = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
case DrawAs::SELECTED: {
|
||||
fill.color = Style::Color(Style::SELECTED).WithAlpha(180);
|
||||
fill.pattern = Canvas::FillPattern::CHECKERED_B;
|
||||
fill.zIndex = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fill.color = RgbaColor::FromFloat(1.0f, 1.0f, 1.0f);
|
||||
pixmap = SS.images[file];
|
||||
break;
|
||||
}
|
||||
|
||||
Canvas::hFill hf = canvas->GetFill(fill);
|
||||
Vector v[4] = {};
|
||||
for(int i = 0; i < 4; i++) {
|
||||
v[i] = SK.GetEntity(point[i])->PointGetNum();
|
||||
}
|
||||
Vector iu = v[3].Minus(v[0]);
|
||||
Vector iv = v[1].Minus(v[0]);
|
||||
|
||||
if(how == DrawAs::DEFAULT && pixmap == NULL) {
|
||||
Canvas::Stroke stroke = Style::Stroke(Style::DRAW_ERROR);
|
||||
stroke.color = stroke.color.WithAlpha(50);
|
||||
Canvas::hStroke hs = canvas->GetStroke(stroke);
|
||||
canvas->DrawLine(v[0], v[2], hs);
|
||||
canvas->DrawLine(v[1], v[3], hs);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
canvas->DrawLine(v[i], v[(i + 1) % 4], hs);
|
||||
}
|
||||
} else {
|
||||
canvas->DrawPixmap(pixmap, v[0], iu, iv,
|
||||
Point2d::From(0.0, 0.0), Point2d::From(1.0, 1.0), hf);
|
||||
}
|
||||
}
|
||||
|
||||
case Type::FACE_NORMAL_PT:
|
||||
case Type::FACE_XPROD:
|
||||
|
|
|
@ -785,7 +785,10 @@ Vector EntityBase::EndpointFinish() const {
|
|||
} else ssassert(false, "Unexpected entity type");
|
||||
}
|
||||
|
||||
void EntityBase::TtfTextGetPointsExprs(ExprVector *eb, ExprVector *ec) const {
|
||||
void EntityBase::RectGetPointsExprs(ExprVector *eb, ExprVector *ec) const {
|
||||
ssassert(type == Type::TTF_TEXT || type == Type::IMAGE,
|
||||
"Unexpected entity type");
|
||||
|
||||
EntityBase *a = SK.GetEntity(point[0]);
|
||||
EntityBase *o = SK.GetEntity(point[1]);
|
||||
|
||||
|
@ -846,6 +849,7 @@ void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) const {
|
|||
break;
|
||||
}
|
||||
|
||||
case Type::IMAGE:
|
||||
case Type::TTF_TEXT: {
|
||||
if(SK.GetEntity(point[0])->type != Type::POINT_IN_2D) break;
|
||||
EntityBase *b = SK.GetEntity(point[2]);
|
||||
|
@ -854,7 +858,7 @@ void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) const {
|
|||
ExprVector ec = c->PointGetExprsInWorkplane(workplane);
|
||||
|
||||
ExprVector ebp, ecp;
|
||||
TtfTextGetPointsExprs(&ebp, &ecp);
|
||||
RectGetPointsExprs(&ebp, &ecp);
|
||||
|
||||
ExprVector beq = eb.Minus(ebp);
|
||||
AddEq(l, beq.x, 0);
|
||||
|
|
79
src/file.cpp
79
src/file.cpp
|
@ -33,6 +33,7 @@ void SolveSpaceUI::ClearExisting() {
|
|||
|
||||
SK.entity.Clear();
|
||||
SK.param.Clear();
|
||||
images.clear();
|
||||
}
|
||||
|
||||
hGroup SolveSpaceUI::CreateDefaultDrawingGroup() {
|
||||
|
@ -131,6 +132,7 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = {
|
|||
{ 'r', "Request.style", 'x', &(SS.sv.r.style) },
|
||||
{ 'r', "Request.str", 'S', &(SS.sv.r.str) },
|
||||
{ 'r', "Request.font", 'S', &(SS.sv.r.font) },
|
||||
{ 'r', "Request.file", 'P', &(SS.sv.r.file) },
|
||||
{ 'r', "Request.aspectRatio", 'f', &(SS.sv.r.aspectRatio) },
|
||||
|
||||
{ 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) },
|
||||
|
@ -139,6 +141,7 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = {
|
|||
{ 'e', "Entity.style", 'x', &(SS.sv.e.style) },
|
||||
{ 'e', "Entity.str", 'S', &(SS.sv.e.str) },
|
||||
{ 'e', "Entity.font", 'S', &(SS.sv.e.font) },
|
||||
{ 'e', "Entity.file", 'P', &(SS.sv.e.file) },
|
||||
{ 'e', "Entity.point[0].v", 'x', &(SS.sv.e.point[0].v) },
|
||||
{ 'e', "Entity.point[1].v", 'x', &(SS.sv.e.point[1].v) },
|
||||
{ 'e', "Entity.point[2].v", 'x', &(SS.sv.e.point[2].v) },
|
||||
|
@ -408,7 +411,10 @@ void SolveSpaceUI::LoadUsingTable(const Platform::Path &filename, char *key, cha
|
|||
case 'x': sscanf(val, "%x", &u); p->x()= u; break;
|
||||
|
||||
case 'P': {
|
||||
p->P() = filename.Parent().Join(Platform::Path::FromPortable(val));
|
||||
Platform::Path path = Platform::Path::FromPortable(val);
|
||||
if(!path.IsEmpty()) {
|
||||
p->P() = filename.Parent().Join(path).Expand();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -537,7 +543,7 @@ bool SolveSpaceUI::LoadFromFile(const Platform::Path &filename, bool canCancel)
|
|||
NewFile();
|
||||
}
|
||||
}
|
||||
if(!ReloadAllImported(filename, canCancel)) {
|
||||
if(!ReloadAllLinked(filename, canCancel)) {
|
||||
return false;
|
||||
}
|
||||
UpgradeLegacyData();
|
||||
|
@ -577,7 +583,7 @@ void SolveSpaceUI::UpgradeLegacyData() {
|
|||
Entity *b = entity.FindById(text->point[2]);
|
||||
Entity *c = entity.FindById(text->point[3]);
|
||||
ExprVector bex, cex;
|
||||
text->TtfTextGetPointsExprs(&bex, &cex);
|
||||
text->RectGetPointsExprs(&bex, &cex);
|
||||
b->PointForceParamTo(bex.Eval());
|
||||
c->PointForceParamTo(cex.Eval());
|
||||
}
|
||||
|
@ -819,11 +825,11 @@ bool SolveSpaceUI::LoadEntitiesFromFile(const Platform::Path &filename, EntityLi
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SolveSpaceUI::ReloadAllImported(const Platform::Path &filename, bool canCancel)
|
||||
{
|
||||
bool SolveSpaceUI::ReloadAllLinked(const Platform::Path &saveFile, bool canCancel) {
|
||||
std::map<Platform::Path, Platform::Path, Platform::PathLess> linkMap;
|
||||
|
||||
allConsistent = false;
|
||||
|
||||
for(Group &g : SK.group) {
|
||||
if(g.type != Group::Type::LINKED) continue;
|
||||
|
||||
|
@ -838,10 +844,16 @@ bool SolveSpaceUI::ReloadAllImported(const Platform::Path &filename, bool canCan
|
|||
|
||||
try_again:
|
||||
if(LoadEntitiesFromFile(g.linkFile, &g.impEntity, &g.impMesh, &g.impShell)) {
|
||||
// We loaded the data, good.
|
||||
// We loaded the data, good. Now import its dependencies as well.
|
||||
for(Entity &e : g.impEntity) {
|
||||
if(e.type != Entity::Type::IMAGE) continue;
|
||||
if(!ReloadLinkedImage(g.linkFile, &e.file, canCancel)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if(linkMap.count(g.linkFile) == 0) {
|
||||
// The file was moved; prompt the user for its new location.
|
||||
switch(LocateImportedFileYesNoCancel(g.linkFile.RelativeTo(filename), canCancel)) {
|
||||
switch(LocateImportedFileYesNoCancel(g.linkFile.RelativeTo(saveFile), canCancel)) {
|
||||
case DIALOG_YES: {
|
||||
Platform::Path newLinkFile;
|
||||
if(GetOpenFile(&newLinkFile, "", SlvsFileFilter)) {
|
||||
|
@ -867,6 +879,59 @@ try_again:
|
|||
}
|
||||
}
|
||||
|
||||
for(Request &r : SK.request) {
|
||||
if(r.type != Request::Type::IMAGE) continue;
|
||||
|
||||
if(!ReloadLinkedImage(saveFile, &r.file, canCancel)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SolveSpaceUI::ReloadLinkedImage(const Platform::Path &saveFile,
|
||||
Platform::Path *filename, bool canCancel) {
|
||||
std::shared_ptr<Pixmap> pixmap;
|
||||
bool promptOpenFile = false;
|
||||
if(filename->IsEmpty()) {
|
||||
// We're prompting the user for a new image.
|
||||
promptOpenFile = true;
|
||||
} else {
|
||||
auto image = SS.images.find(*filename);
|
||||
if(image != SS.images.end()) return true;
|
||||
|
||||
pixmap = Pixmap::ReadPng(*filename);
|
||||
if(pixmap == NULL) {
|
||||
// The file was moved; prompt the user for its new location.
|
||||
switch(LocateImportedFileYesNoCancel(filename->RelativeTo(saveFile), canCancel)) {
|
||||
case DIALOG_YES:
|
||||
promptOpenFile = true;
|
||||
break;
|
||||
|
||||
case DIALOG_NO:
|
||||
// We don't know where the file is, record it as absent.
|
||||
break;
|
||||
|
||||
case DIALOG_CANCEL:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(promptOpenFile) {
|
||||
if(GetOpenFile(filename, "", RasterFileFilter)) {
|
||||
pixmap = Pixmap::ReadPng(*filename);
|
||||
if(pixmap == NULL) {
|
||||
Error("The image '%s' is corrupted.", filename->raw.c_str());
|
||||
}
|
||||
// We know where the file is now, good.
|
||||
} else if(canCancel) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We loaded the data, good.
|
||||
SS.images[*filename] = pixmap;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
|||
{ 1, N_("&Bezier Cubic Spline"), Command::CUBIC, 'B', TN, mReq },
|
||||
{ 1, NULL, Command::NONE, 0, TN, NULL },
|
||||
{ 1, N_("&Text in TrueType Font"), Command::TTF_TEXT, 'T', TN, mReq },
|
||||
{ 1, N_("&Image"), Command::IMAGE, 0, TN, mReq },
|
||||
{ 1, NULL, Command::NONE, 0, TN, NULL },
|
||||
{ 1, N_("To&ggle Construction"), Command::CONSTRUCTION, 'G', TN, mReq },
|
||||
{ 1, N_("Tangent &Arc at Point"), Command::TANGENT_ARC, S|'A', TN, mReq },
|
||||
|
@ -943,7 +944,8 @@ void GraphicsWindow::MenuEdit(Command id) {
|
|||
break;
|
||||
|
||||
case Command::REGEN_ALL:
|
||||
SS.ReloadAllImported(SS.saveFile);
|
||||
SS.images.clear();
|
||||
SS.ReloadAllLinked(SS.saveFile);
|
||||
SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE);
|
||||
SS.ScheduleShowTW();
|
||||
break;
|
||||
|
@ -1015,6 +1017,12 @@ void GraphicsWindow::MenuRequest(Command id) {
|
|||
case Command::WORKPLANE: s = _("click origin of workplane"); goto c;
|
||||
case Command::RECTANGLE: s = _("click one corner of rectangle"); goto c;
|
||||
case Command::TTF_TEXT: s = _("click top left of text"); goto c;
|
||||
case Command::IMAGE:
|
||||
if(!SS.ReloadLinkedImage(SS.saveFile, &SS.GW.pending.filename,
|
||||
/*canCancel=*/true)) {
|
||||
return;
|
||||
}
|
||||
s = _("click top left of image"); goto c;
|
||||
c:
|
||||
SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND;
|
||||
SS.GW.pending.command = id;
|
||||
|
|
|
@ -274,7 +274,7 @@ void Group::MenuGroup(Command id) {
|
|||
Group *gg = SK.GetGroup(g.h);
|
||||
|
||||
if(gg->type == Type::LINKED) {
|
||||
SS.ReloadAllImported(SS.saveFile);
|
||||
SS.ReloadAllLinked(SS.saveFile);
|
||||
}
|
||||
gg->clean = false;
|
||||
SS.GW.activeGroup = gg->h;
|
||||
|
@ -801,6 +801,7 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
|
|||
en.style = ep->style;
|
||||
en.str = ep->str;
|
||||
en.font = ep->font;
|
||||
en.file = ep->file;
|
||||
|
||||
switch(ep->type) {
|
||||
case Entity::Type::WORKPLANE:
|
||||
|
|
|
@ -51,7 +51,8 @@ void GraphicsWindow::StartDraggingByEntity(hEntity he) {
|
|||
e->type == Entity::Type::CUBIC ||
|
||||
e->type == Entity::Type::CUBIC_PERIODIC ||
|
||||
e->type == Entity::Type::CIRCLE ||
|
||||
e->type == Entity::Type::TTF_TEXT)
|
||||
e->type == Entity::Type::TTF_TEXT ||
|
||||
e->type == Entity::Type::IMAGE)
|
||||
{
|
||||
int pts;
|
||||
EntReqTable::GetEntityInfo(e->type, e->extraPoints,
|
||||
|
@ -1146,6 +1147,27 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
break;
|
||||
}
|
||||
|
||||
case Command::IMAGE: {
|
||||
if(!SS.GW.LockedInWorkplane()) {
|
||||
Error(_("Can't draw image in 3d; first, activate a workplane "
|
||||
"with Sketch -> In Workplane."));
|
||||
ClearSuper();
|
||||
break;
|
||||
}
|
||||
hr = AddRequest(Request::Type::IMAGE);
|
||||
AddToPending(hr);
|
||||
Request *r = SK.GetRequest(hr);
|
||||
r->file = pending.filename;
|
||||
|
||||
SK.GetEntity(hr.entity(1))->PointForceTo(v);
|
||||
SK.GetEntity(hr.entity(2))->PointForceTo(v);
|
||||
|
||||
pending.operation = Pending::DRAGGING_NEW_POINT;
|
||||
pending.point = hr.entity(2);
|
||||
pending.description = "click to place bottom left of image";
|
||||
break;
|
||||
}
|
||||
|
||||
case Command::COMMENT: {
|
||||
ClearSuper();
|
||||
Constraint c = {};
|
||||
|
|
|
@ -76,7 +76,7 @@ File formats:
|
|||
export-wireframe:%s
|
||||
export-mesh:%s
|
||||
export-surfaces:%s
|
||||
)", FormatListFromFileFilter(PngFileFilter).c_str(),
|
||||
)", FormatListFromFileFilter(RasterFileFilter).c_str(),
|
||||
FormatListFromFileFilter(VectorFileFilter).c_str(),
|
||||
FormatListFromFileFilter(Vector3dFileFilter).c_str(),
|
||||
FormatListFromFileFilter(MeshFileFilter).c_str(),
|
||||
|
|
|
@ -441,7 +441,7 @@ void ObjectPicker::DrawFaces(const SMesh &m, const std::vector<uint32_t> &faces,
|
|||
void ObjectPicker::DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
||||
const Vector &o, const Vector &u, const Vector &v,
|
||||
const Point2d &ta, const Point2d &tb, Canvas::hFill hcf) {
|
||||
ssassert(false, "Not implemented");
|
||||
DrawQuad(o, o.Plus(u), o.Plus(u).Plus(v), o.Plus(v), hcf);
|
||||
}
|
||||
|
||||
bool ObjectPicker::Pick(std::function<void()> drawFn) {
|
||||
|
|
|
@ -769,11 +769,11 @@ public:
|
|||
virtual Canvas::Layer GetLayer() const override { return stroke.layer; };
|
||||
virtual int GetZIndex() const override { return stroke.zIndex; };
|
||||
|
||||
static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SIndexedMesh &im,
|
||||
static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SIndexedMesh &mesh,
|
||||
Canvas::Stroke *stroke) {
|
||||
PointDrawCall *dc = new PointDrawCall();
|
||||
dc->stroke = *stroke;
|
||||
dc->handle = renderer->imeshRenderer.Add(im);
|
||||
dc->handle = renderer->imeshRenderer.Add(mesh);
|
||||
return std::shared_ptr<DrawCall>(dc);
|
||||
}
|
||||
|
||||
|
@ -788,6 +788,42 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class PixmapDrawCall : public DrawCall {
|
||||
public:
|
||||
// Key
|
||||
Canvas::Fill fill;
|
||||
// Data
|
||||
IndexedMeshRenderer::Handle handle;
|
||||
|
||||
virtual Canvas::Layer GetLayer() const override { return fill.layer; };
|
||||
virtual int GetZIndex() const override { return fill.zIndex; };
|
||||
|
||||
static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SIndexedMesh &mesh,
|
||||
Canvas::Fill *fill) {
|
||||
PixmapDrawCall *dc = new PixmapDrawCall();
|
||||
dc->fill = *fill;
|
||||
dc->handle = renderer->imeshRenderer.Add(mesh);
|
||||
return std::shared_ptr<DrawCall>(dc);
|
||||
}
|
||||
|
||||
void Draw(OpenGl2Renderer *renderer) override {
|
||||
ssglDepthRange(fill.layer, fill.zIndex);
|
||||
if(fill.pattern != Canvas::FillPattern::SOLID) {
|
||||
renderer->SelectMask(fill.pattern);
|
||||
} else if(fill.texture) {
|
||||
renderer->SelectTexture(fill.texture);
|
||||
} else {
|
||||
renderer->SelectMask(Canvas::FillPattern::SOLID);
|
||||
}
|
||||
renderer->imeshRenderer.UseFilled(fill);
|
||||
renderer->imeshRenderer.Draw(handle);
|
||||
}
|
||||
|
||||
void Remove(OpenGl2Renderer *renderer) override {
|
||||
renderer->imeshRenderer.Remove(handle);
|
||||
}
|
||||
};
|
||||
|
||||
class MeshDrawCall : public DrawCall {
|
||||
public:
|
||||
// Key
|
||||
|
@ -813,22 +849,22 @@ public:
|
|||
return std::shared_ptr<DrawCall>(dc);
|
||||
}
|
||||
|
||||
void DrawFace(OpenGl2Renderer *renderer, GLenum cullFace, Canvas::Fill *fill) {
|
||||
void DrawFace(OpenGl2Renderer *renderer, GLenum cullFace, const Canvas::Fill &fill) {
|
||||
glCullFace(cullFace);
|
||||
ssglDepthRange(fill->layer, fill->zIndex);
|
||||
if(fill->pattern != Canvas::FillPattern::SOLID) {
|
||||
renderer->SelectMask(fill->pattern);
|
||||
} else if(fill->texture) {
|
||||
renderer->SelectTexture(fill->texture);
|
||||
ssglDepthRange(fill.layer, fill.zIndex);
|
||||
if(fill.pattern != Canvas::FillPattern::SOLID) {
|
||||
renderer->SelectMask(fill.pattern);
|
||||
} else if(fill.texture) {
|
||||
renderer->SelectTexture(fill.texture);
|
||||
} else {
|
||||
renderer->SelectMask(Canvas::FillPattern::SOLID);
|
||||
}
|
||||
if(isShaded) {
|
||||
renderer->meshRenderer.UseShaded(renderer->lighting);
|
||||
} else {
|
||||
renderer->meshRenderer.UseFilled(*fill);
|
||||
renderer->meshRenderer.UseFilled(fill);
|
||||
}
|
||||
renderer->meshRenderer.Draw(handle, /*useColors=*/fill->color.IsEmpty(), fill->color);
|
||||
renderer->meshRenderer.Draw(handle, /*useColors=*/fill.color.IsEmpty(), fill.color);
|
||||
}
|
||||
|
||||
void Draw(OpenGl2Renderer *renderer) override {
|
||||
|
@ -836,8 +872,8 @@ public:
|
|||
glEnable(GL_CULL_FACE);
|
||||
|
||||
if(hasFillBack)
|
||||
DrawFace(renderer, GL_FRONT, &fillBack);
|
||||
DrawFace(renderer, GL_BACK, &fillFront);
|
||||
DrawFace(renderer, GL_FRONT, fillBack);
|
||||
DrawFace(renderer, GL_BACK, fillFront);
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
@ -977,7 +1013,14 @@ public:
|
|||
void DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
||||
const Vector &o, const Vector &u, const Vector &v,
|
||||
const Point2d &ta, const Point2d &tb, hFill hcf) override {
|
||||
ssassert(false, "Not implemented");
|
||||
Fill fill = *fills.FindById(hcf);
|
||||
fill.texture = pm;
|
||||
hcf = GetFill(fill);
|
||||
|
||||
SIndexedMesh mesh = {};
|
||||
mesh.AddPixmap(o, u, v, ta, tb);
|
||||
drawCalls.emplace(PixmapDrawCall::Create(renderer, mesh, fills.FindByIdNoOops(hcf)));
|
||||
mesh.Clear();
|
||||
}
|
||||
|
||||
void InvalidatePixmap(std::shared_ptr<const Pixmap> pm) override {
|
||||
|
|
|
@ -30,6 +30,7 @@ static const EntReqMapping EntReqMap[] = {
|
|||
{ Request::Type::CIRCLE, Entity::Type::CIRCLE, 1, false, true, true },
|
||||
{ Request::Type::ARC_OF_CIRCLE, Entity::Type::ARC_OF_CIRCLE, 3, false, true, false },
|
||||
{ Request::Type::TTF_TEXT, Entity::Type::TTF_TEXT, 4, false, true, false },
|
||||
{ Request::Type::IMAGE, Entity::Type::IMAGE, 4, false, true, false },
|
||||
};
|
||||
|
||||
static void CopyEntityInfo(const EntReqMapping *te, int extraPoints,
|
||||
|
@ -102,6 +103,20 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
|
|||
break;
|
||||
}
|
||||
|
||||
case Type::IMAGE: {
|
||||
auto image = SS.images.find(file);
|
||||
if(image != SS.images.end()) {
|
||||
std::shared_ptr<Pixmap> pixmap = (*image).second;
|
||||
if(pixmap != NULL) {
|
||||
aspectRatio = (double)pixmap->width / (double)pixmap->height;
|
||||
}
|
||||
}
|
||||
if(EXACT(aspectRatio == 0.0)) {
|
||||
aspectRatio = 1.0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: // most requests don't do anything else
|
||||
break;
|
||||
}
|
||||
|
@ -118,6 +133,7 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
|
|||
e.construction = construction;
|
||||
e.str = str;
|
||||
e.font = font;
|
||||
e.file = file;
|
||||
e.aspectRatio = aspectRatio;
|
||||
e.h = h.entity(0);
|
||||
|
||||
|
@ -205,8 +221,9 @@ std::string Request::DescriptionString() const {
|
|||
case Type::CUBIC: s = "cubic-bezier"; break;
|
||||
case Type::CUBIC_PERIODIC: s = "periodic-cubic"; break;
|
||||
case Type::CIRCLE: s = "circle"; break;
|
||||
case Type::ARC_OF_CIRCLE: s = "arc-of-circle;"; break;
|
||||
case Type::ARC_OF_CIRCLE: s = "arc-of-circle"; break;
|
||||
case Type::TTF_TEXT: s = "ttf-text"; break;
|
||||
case Type::IMAGE: s = "image"; break;
|
||||
}
|
||||
}
|
||||
ssassert(s != NULL, "Unexpected request type");
|
||||
|
|
10
src/sketch.h
10
src/sketch.h
|
@ -312,7 +312,8 @@ public:
|
|||
CUBIC_PERIODIC = 301,
|
||||
CIRCLE = 400,
|
||||
ARC_OF_CIRCLE = 500,
|
||||
TTF_TEXT = 600
|
||||
TTF_TEXT = 600,
|
||||
IMAGE = 700
|
||||
};
|
||||
|
||||
Request::Type type;
|
||||
|
@ -326,6 +327,7 @@ public:
|
|||
|
||||
std::string str;
|
||||
std::string font;
|
||||
Platform::Path file;
|
||||
double aspectRatio;
|
||||
|
||||
static hParam AddParam(ParamList *param, hParam hp);
|
||||
|
@ -375,7 +377,8 @@ public:
|
|||
CUBIC_PERIODIC = 12001,
|
||||
CIRCLE = 13000,
|
||||
ARC_OF_CIRCLE = 14000,
|
||||
TTF_TEXT = 15000
|
||||
TTF_TEXT = 15000,
|
||||
IMAGE = 16000
|
||||
};
|
||||
|
||||
Type type;
|
||||
|
@ -400,6 +403,7 @@ public:
|
|||
|
||||
std::string str;
|
||||
std::string font;
|
||||
Platform::Path file;
|
||||
double aspectRatio;
|
||||
|
||||
// For entities that are derived by a transformation, the number of
|
||||
|
@ -476,7 +480,7 @@ public:
|
|||
Vector EndpointStart() const;
|
||||
Vector EndpointFinish() const;
|
||||
|
||||
void TtfTextGetPointsExprs(ExprVector *eap, ExprVector *ebp) const;
|
||||
void RectGetPointsExprs(ExprVector *eap, ExprVector *ebp) const;
|
||||
|
||||
void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) const;
|
||||
void GenerateEquations(IdList<Equation,hEquation> *l) const;
|
||||
|
|
|
@ -457,7 +457,7 @@ void SolveSpaceUI::MenuFile(Command id) {
|
|||
|
||||
case Command::EXPORT_PNG: {
|
||||
Platform::Path exportFile = SS.saveFile;
|
||||
if(!GetSaveFile(&exportFile, "", PngFileFilter)) break;
|
||||
if(!GetSaveFile(&exportFile, "", RasterFileFilter)) break;
|
||||
SS.ExportAsPngTo(exportFile);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -620,6 +620,11 @@ public:
|
|||
} UndoStack;
|
||||
UndoStack undo;
|
||||
UndoStack redo;
|
||||
|
||||
std::map<Platform::Path, std::shared_ptr<Pixmap>, Platform::PathLess> images;
|
||||
bool ReloadLinkedImage(const Platform::Path &saveFile, Platform::Path *filename,
|
||||
bool canCancel);
|
||||
|
||||
void UndoEnableMenus();
|
||||
void UndoRemember();
|
||||
void UndoUndo();
|
||||
|
@ -743,7 +748,7 @@ public:
|
|||
void UpgradeLegacyData();
|
||||
bool LoadEntitiesFromFile(const Platform::Path &filename, EntityList *le,
|
||||
SMesh *m, SShell *sh);
|
||||
bool ReloadAllImported(const Platform::Path &filename, bool canCancel = false);
|
||||
bool ReloadAllLinked(const Platform::Path &filename, bool canCancel = false);
|
||||
// And the various export options
|
||||
void ExportAsPngTo(const Platform::Path &filename);
|
||||
void ExportMeshTo(const Platform::Path &filename);
|
||||
|
|
|
@ -394,7 +394,7 @@ void TextWindow::ScreenBackgroundImage(int link, uint32_t v) {
|
|||
|
||||
if(link == 'l') {
|
||||
Platform::Path bgImageFile;
|
||||
if(GetOpenFile(&bgImageFile, "", PngFileFilter)) {
|
||||
if(GetOpenFile(&bgImageFile, "", RasterFileFilter)) {
|
||||
FILE *f = OpenFile(bgImageFile, "rb");
|
||||
if(f) {
|
||||
SS.bgImage.pixmap = Pixmap::ReadPng(f);
|
||||
|
|
|
@ -327,7 +327,7 @@ void TextWindow::ShowGroupInfo() {
|
|||
}
|
||||
} else if(g->type == Group::Type::LINKED) {
|
||||
Printf(true, " %Ftlink geometry from file%E");
|
||||
Platform::Path relativePath =g->linkFile.RelativeTo(SS.saveFile.Parent());
|
||||
Platform::Path relativePath = g->linkFile.RelativeTo(SS.saveFile.Parent());
|
||||
if(relativePath.IsEmpty()) {
|
||||
Printf(false, "%Ba '%s'", g->linkFile.raw.c_str());
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,8 @@ static ToolIcon Toolbar[] = {
|
|||
N_("Sketch arc of a circle"), {} },
|
||||
{ "text", Command::TTF_TEXT,
|
||||
N_("Sketch curves from text in a TrueType font"), {} },
|
||||
{ "image", Command::IMAGE,
|
||||
N_("Sketch image from a file"), {} },
|
||||
{ "tangent-arc", Command::TANGENT_ARC,
|
||||
N_("Create tangent arc at selected point"), {} },
|
||||
{ "bezier", Command::CUBIC,
|
||||
|
|
4
src/ui.h
4
src/ui.h
|
@ -70,7 +70,7 @@ const FileFilter SlvsFileFilter[] = {
|
|||
{ NULL, {} }
|
||||
};
|
||||
// PNG format bitmap
|
||||
const FileFilter PngFileFilter[] = {
|
||||
const FileFilter RasterFileFilter[] = {
|
||||
{ N_("PNG file"), { "png" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
|
@ -173,6 +173,7 @@ enum class Command : uint32_t {
|
|||
RECTANGLE,
|
||||
CUBIC,
|
||||
TTF_TEXT,
|
||||
IMAGE,
|
||||
SPLIT_CURVES,
|
||||
TANGENT_ARC,
|
||||
CONSTRUCTION,
|
||||
|
@ -712,6 +713,7 @@ public:
|
|||
hConstraint constraint;
|
||||
|
||||
const char *description;
|
||||
Platform::Path filename;
|
||||
|
||||
bool hasSuggestion;
|
||||
Constraint::Type suggestion;
|
||||
|
|
|
@ -138,7 +138,7 @@ void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
|||
// sketch just changed a lot.
|
||||
SS.GW.ClearSuper();
|
||||
SS.TW.ClearSuper();
|
||||
SS.ReloadAllImported(SS.saveFile);
|
||||
SS.ReloadAllLinked(SS.saveFile);
|
||||
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
|
||||
SS.ScheduleShowTW();
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ set(testsuite_SOURCES
|
|||
request/cubic/test.cpp
|
||||
request/cubic_periodic/test.cpp
|
||||
request/datum_point/test.cpp
|
||||
request/image/test.cpp
|
||||
request/line_segment/test.cpp
|
||||
request/ttf_text/test.cpp
|
||||
group/link/test.cpp
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
|
@ -0,0 +1,430 @@
|
|||
±²³SolveSpaceREVa
|
||||
|
||||
|
||||
Group.h.v=00000001
|
||||
Group.type=5000
|
||||
Group.name=#references
|
||||
Group.color=ff000000
|
||||
Group.skipFirst=0
|
||||
Group.predef.swapUV=0
|
||||
Group.predef.negateU=0
|
||||
Group.predef.negateV=0
|
||||
Group.visible=1
|
||||
Group.suppress=0
|
||||
Group.relaxConstraints=0
|
||||
Group.allowRedundant=0
|
||||
Group.allDimsReference=0
|
||||
Group.scale=1.00000000000000000000
|
||||
Group.remap={
|
||||
}
|
||||
AddGroup
|
||||
|
||||
Group.h.v=00000002
|
||||
Group.type=5001
|
||||
Group.order=1
|
||||
Group.name=sketch-in-plane
|
||||
Group.activeWorkplane.v=80020000
|
||||
Group.color=ff000000
|
||||
Group.subtype=6000
|
||||
Group.skipFirst=0
|
||||
Group.predef.q.w=1.00000000000000000000
|
||||
Group.predef.origin.v=00010001
|
||||
Group.predef.swapUV=0
|
||||
Group.predef.negateU=0
|
||||
Group.predef.negateV=0
|
||||
Group.visible=1
|
||||
Group.suppress=0
|
||||
Group.relaxConstraints=0
|
||||
Group.allowRedundant=0
|
||||
Group.allDimsReference=0
|
||||
Group.scale=1.00000000000000000000
|
||||
Group.remap={
|
||||
}
|
||||
AddGroup
|
||||
|
||||
Group.h.v=00000003
|
||||
Group.type=5300
|
||||
Group.order=2
|
||||
Group.name=normal
|
||||
Group.activeWorkplane.v=00010000
|
||||
Group.color=00646464
|
||||
Group.skipFirst=0
|
||||
Group.meshCombine=2
|
||||
Group.predef.swapUV=0
|
||||
Group.predef.negateU=0
|
||||
Group.predef.negateV=0
|
||||
Group.visible=1
|
||||
Group.suppress=0
|
||||
Group.relaxConstraints=0
|
||||
Group.allowRedundant=0
|
||||
Group.allDimsReference=0
|
||||
Group.scale=1.00000000000000000000
|
||||
Group.remap={
|
||||
1 00010000 0
|
||||
2 00010001 0
|
||||
3 00010020 0
|
||||
4 00020000 0
|
||||
5 00020001 0
|
||||
6 00020020 0
|
||||
7 00030000 0
|
||||
8 00030001 0
|
||||
9 00030020 0
|
||||
10 00040000 0
|
||||
11 00040001 0
|
||||
12 00040002 0
|
||||
13 00040003 0
|
||||
14 00040004 0
|
||||
15 00040020 0
|
||||
16 80020000 0
|
||||
17 80020001 0
|
||||
18 80020002 0
|
||||
}
|
||||
Group.impFileRel=normal.slvs
|
||||
AddGroup
|
||||
|
||||
Param.h.v.=00010010
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010011
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010012
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010020
|
||||
Param.val=1.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010021
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010022
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010023
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020010
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020011
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020012
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020020
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020021
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020022
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020023
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030010
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030011
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030012
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030020
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030021
|
||||
Param.val=-0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030022
|
||||
Param.val=-0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030023
|
||||
Param.val=-0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=40000001
|
||||
Param.val=1.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=80030000
|
||||
Param.val=5.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=80030001
|
||||
Param.val=5.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=80030002
|
||||
AddParam
|
||||
|
||||
Param.h.v.=80030003
|
||||
Param.val=1.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=80030004
|
||||
AddParam
|
||||
|
||||
Param.h.v.=80030005
|
||||
AddParam
|
||||
|
||||
Param.h.v.=80030006
|
||||
AddParam
|
||||
|
||||
Request.h.v=00000001
|
||||
Request.type=100
|
||||
Request.group.v=00000001
|
||||
Request.construction=0
|
||||
AddRequest
|
||||
|
||||
Request.h.v=00000002
|
||||
Request.type=100
|
||||
Request.group.v=00000001
|
||||
Request.construction=0
|
||||
AddRequest
|
||||
|
||||
Request.h.v=00000003
|
||||
Request.type=100
|
||||
Request.group.v=00000001
|
||||
Request.construction=0
|
||||
AddRequest
|
||||
|
||||
Entity.h.v=00010000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00010001
|
||||
Entity.normal.v=00010020
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00010001
|
||||
Entity.type=2000
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00010020
|
||||
Entity.type=3000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00010001
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00020000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00020001
|
||||
Entity.normal.v=00020020
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00020001
|
||||
Entity.type=2000
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00020020
|
||||
Entity.type=3000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00020001
|
||||
Entity.actNormal.w=0.50000000000000000000
|
||||
Entity.actNormal.vx=0.50000000000000000000
|
||||
Entity.actNormal.vy=0.50000000000000000000
|
||||
Entity.actNormal.vz=0.50000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00030000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00030001
|
||||
Entity.normal.v=00030020
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00030001
|
||||
Entity.type=2000
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00030020
|
||||
Entity.type=3000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00030001
|
||||
Entity.actNormal.w=0.50000000000000000000
|
||||
Entity.actNormal.vx=-0.50000000000000000000
|
||||
Entity.actNormal.vy=-0.50000000000000000000
|
||||
Entity.actNormal.vz=-0.50000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80020000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80020002
|
||||
Entity.normal.v=80020001
|
||||
Entity.actVisible=0
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80020001
|
||||
Entity.type=3010
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80020002
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80020002
|
||||
Entity.type=2012
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030002
|
||||
Entity.type=2011
|
||||
Entity.construction=1
|
||||
Entity.actPoint.x=5.00000000000000000000
|
||||
Entity.actPoint.y=5.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030003
|
||||
Entity.type=3011
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80030002
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030005
|
||||
Entity.type=2011
|
||||
Entity.construction=1
|
||||
Entity.actPoint.x=5.00000000000000000000
|
||||
Entity.actPoint.y=5.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030006
|
||||
Entity.type=3011
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80030005
|
||||
Entity.actNormal.w=0.50000000000000000000
|
||||
Entity.actNormal.vx=0.50000000000000000000
|
||||
Entity.actNormal.vy=0.50000000000000000000
|
||||
Entity.actNormal.vz=0.50000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030008
|
||||
Entity.type=2011
|
||||
Entity.construction=1
|
||||
Entity.actPoint.x=5.00000000000000000000
|
||||
Entity.actPoint.y=5.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030009
|
||||
Entity.type=3011
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80030008
|
||||
Entity.actNormal.w=0.50000000000000000000
|
||||
Entity.actNormal.vx=-0.50000000000000000000
|
||||
Entity.actNormal.vy=-0.50000000000000000000
|
||||
Entity.actNormal.vz=-0.50000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=8003000a
|
||||
Entity.type=16000
|
||||
Entity.construction=0
|
||||
Entity.file=drawing.png
|
||||
Entity.point[0].v=8003000b
|
||||
Entity.point[1].v=8003000c
|
||||
Entity.point[2].v=8003000d
|
||||
Entity.point[3].v=8003000e
|
||||
Entity.normal.v=8003000f
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=8003000b
|
||||
Entity.type=2011
|
||||
Entity.construction=0
|
||||
Entity.actPoint.x=5.00000000000000000000
|
||||
Entity.actPoint.y=15.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=8003000c
|
||||
Entity.type=2011
|
||||
Entity.construction=0
|
||||
Entity.actPoint.x=5.00000000000000000000
|
||||
Entity.actPoint.y=5.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=8003000d
|
||||
Entity.type=2011
|
||||
Entity.construction=0
|
||||
Entity.actPoint.x=20.00000000000000000000
|
||||
Entity.actPoint.y=5.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=8003000e
|
||||
Entity.type=2011
|
||||
Entity.construction=0
|
||||
Entity.actPoint.x=20.00000000000000000000
|
||||
Entity.actPoint.y=15.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=8003000f
|
||||
Entity.type=3011
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=8003000b
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030011
|
||||
Entity.type=3011
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80030012
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80030012
|
||||
Entity.type=2011
|
||||
Entity.construction=1
|
||||
Entity.actPoint.x=5.00000000000000000000
|
||||
Entity.actPoint.y=5.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Constraint.h.v=00000001
|
||||
Constraint.type=110
|
||||
Constraint.group.v=00000003
|
||||
Constraint.workplane.v=00010000
|
||||
Constraint.valP.v=40000001
|
||||
Constraint.entityA.v=80030006
|
||||
Constraint.entityB.v=00020020
|
||||
Constraint.other=0
|
||||
Constraint.other2=0
|
||||
Constraint.reference=0
|
||||
AddConstraint
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
±²³SolveSpaceREVa
|
||||
|
||||
|
||||
Group.h.v=00000001
|
||||
Group.type=5000
|
||||
Group.name=#references
|
||||
Group.color=ff000000
|
||||
Group.skipFirst=0
|
||||
Group.predef.swapUV=0
|
||||
Group.predef.negateU=0
|
||||
Group.predef.negateV=0
|
||||
Group.visible=1
|
||||
Group.suppress=0
|
||||
Group.relaxConstraints=0
|
||||
Group.allowRedundant=0
|
||||
Group.allDimsReference=0
|
||||
Group.scale=1.00000000000000000000
|
||||
Group.remap={
|
||||
}
|
||||
AddGroup
|
||||
|
||||
Group.h.v=00000002
|
||||
Group.type=5001
|
||||
Group.order=1
|
||||
Group.name=sketch-in-plane
|
||||
Group.activeWorkplane.v=80020000
|
||||
Group.color=ff000000
|
||||
Group.subtype=6000
|
||||
Group.skipFirst=0
|
||||
Group.predef.q.w=1.00000000000000000000
|
||||
Group.predef.origin.v=00010001
|
||||
Group.predef.swapUV=0
|
||||
Group.predef.negateU=0
|
||||
Group.predef.negateV=0
|
||||
Group.visible=1
|
||||
Group.suppress=0
|
||||
Group.relaxConstraints=0
|
||||
Group.allowRedundant=0
|
||||
Group.allDimsReference=0
|
||||
Group.scale=1.00000000000000000000
|
||||
Group.remap={
|
||||
}
|
||||
AddGroup
|
||||
|
||||
Param.h.v.=00010010
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010011
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010012
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010020
|
||||
Param.val=1.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010021
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010022
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00010023
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020010
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020011
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020012
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020020
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020021
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020022
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00020023
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030010
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030011
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030012
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030020
|
||||
Param.val=0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030021
|
||||
Param.val=-0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030022
|
||||
Param.val=-0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00030023
|
||||
Param.val=-0.50000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00040010
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00040011
|
||||
Param.val=10.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00040013
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00040014
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00040016
|
||||
Param.val=15.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00040017
|
||||
AddParam
|
||||
|
||||
Param.h.v.=00040019
|
||||
Param.val=15.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Param.h.v.=0004001a
|
||||
Param.val=10.00000000000000000000
|
||||
AddParam
|
||||
|
||||
Request.h.v=00000001
|
||||
Request.type=100
|
||||
Request.group.v=00000001
|
||||
Request.construction=0
|
||||
AddRequest
|
||||
|
||||
Request.h.v=00000002
|
||||
Request.type=100
|
||||
Request.group.v=00000001
|
||||
Request.construction=0
|
||||
AddRequest
|
||||
|
||||
Request.h.v=00000003
|
||||
Request.type=100
|
||||
Request.group.v=00000001
|
||||
Request.construction=0
|
||||
AddRequest
|
||||
|
||||
Request.h.v=00000004
|
||||
Request.type=700
|
||||
Request.workplane.v=80020000
|
||||
Request.group.v=00000002
|
||||
Request.construction=0
|
||||
Request.file=drawing.png
|
||||
Request.aspectRatio=1.50000000000000000000
|
||||
AddRequest
|
||||
|
||||
Entity.h.v=00010000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00010001
|
||||
Entity.normal.v=00010020
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00010001
|
||||
Entity.type=2000
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00010020
|
||||
Entity.type=3000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00010001
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00020000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00020001
|
||||
Entity.normal.v=00020020
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00020001
|
||||
Entity.type=2000
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00020020
|
||||
Entity.type=3000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00020001
|
||||
Entity.actNormal.w=0.50000000000000000000
|
||||
Entity.actNormal.vx=0.50000000000000000000
|
||||
Entity.actNormal.vy=0.50000000000000000000
|
||||
Entity.actNormal.vz=0.50000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00030000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00030001
|
||||
Entity.normal.v=00030020
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00030001
|
||||
Entity.type=2000
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00030020
|
||||
Entity.type=3000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00030001
|
||||
Entity.actNormal.w=0.50000000000000000000
|
||||
Entity.actNormal.vx=-0.50000000000000000000
|
||||
Entity.actNormal.vy=-0.50000000000000000000
|
||||
Entity.actNormal.vz=-0.50000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00040000
|
||||
Entity.type=16000
|
||||
Entity.construction=0
|
||||
Entity.file=drawing.png
|
||||
Entity.point[0].v=00040001
|
||||
Entity.point[1].v=00040002
|
||||
Entity.point[2].v=00040003
|
||||
Entity.point[3].v=00040004
|
||||
Entity.normal.v=00040020
|
||||
Entity.workplane.v=80020000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00040001
|
||||
Entity.type=2001
|
||||
Entity.construction=0
|
||||
Entity.workplane.v=80020000
|
||||
Entity.actPoint.y=10.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00040002
|
||||
Entity.type=2001
|
||||
Entity.construction=0
|
||||
Entity.workplane.v=80020000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00040003
|
||||
Entity.type=2001
|
||||
Entity.construction=0
|
||||
Entity.workplane.v=80020000
|
||||
Entity.actPoint.x=15.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00040004
|
||||
Entity.type=2001
|
||||
Entity.construction=0
|
||||
Entity.workplane.v=80020000
|
||||
Entity.actPoint.x=15.00000000000000000000
|
||||
Entity.actPoint.y=10.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=00040020
|
||||
Entity.type=3001
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=00040001
|
||||
Entity.workplane.v=80020000
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80020000
|
||||
Entity.type=10000
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80020002
|
||||
Entity.normal.v=80020001
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80020001
|
||||
Entity.type=3010
|
||||
Entity.construction=0
|
||||
Entity.point[0].v=80020002
|
||||
Entity.actNormal.w=1.00000000000000000000
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
||||
Entity.h.v=80020002
|
||||
Entity.type=2012
|
||||
Entity.construction=1
|
||||
Entity.actVisible=1
|
||||
AddEntity
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#include "harness.h"
|
||||
|
||||
TEST_CASE(normal_roundtrip) {
|
||||
CHECK_LOAD("normal.slvs");
|
||||
// Can't render images through cairo for now.
|
||||
// CHECK_RENDER("normal.png");
|
||||
CHECK_SAVE("normal.slvs");
|
||||
}
|
||||
|
||||
TEST_CASE(linked_roundtrip) {
|
||||
CHECK_LOAD("linked.slvs");
|
||||
// CHECK_RENDER("linked.png");
|
||||
CHECK_SAVE("linked.slvs");
|
||||
}
|
Loading…
Reference in New Issue