summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/drawpath3.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/drawpath3.cc')
-rw-r--r--Build/source/utils/asymptote/drawpath3.cc264
1 files changed, 264 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/drawpath3.cc b/Build/source/utils/asymptote/drawpath3.cc
new file mode 100644
index 00000000000..088d2705db9
--- /dev/null
+++ b/Build/source/utils/asymptote/drawpath3.cc
@@ -0,0 +1,264 @@
+/*****
+ * drawpath3.cc
+ *
+ * Stores a path3 that has been added to a picture.
+ *****/
+
+#include "drawpath3.h"
+#include "drawsurface.h"
+#include "material.h"
+
+#ifdef HAVE_LIBGLM
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#endif
+
+namespace camp {
+
+using vm::array;
+using namespace prc;
+
+bool drawPath3::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ if(straight) {
+ triple controls[]={g.point((Int) 0),g.point((Int) 1)};
+ out->addLine(2,controls,diffuse);
+ } else {
+ triple controls[]={g.point((Int) 0),g.postcontrol((Int) 0),
+ g.precontrol((Int) 1),g.point((Int) 1)};
+ out->addBezierCurve(4,controls,diffuse);
+ }
+
+ return true;
+}
+
+bool drawPath3::write(jsfile *out)
+{
+#ifdef HAVE_LIBGLM
+ if(invisible)
+ return true;
+
+ if(billboard) {
+ meshinit();
+ drawElement::centerIndex=centerIndex;
+ } else drawElement::centerIndex=0;
+
+ setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
+ if(straight)
+ out->addCurve(g.point((Int) 0),g.point((Int) 1),Min,Max);
+ else
+ out->addCurve(g.point((Int) 0),g.postcontrol((Int) 0),
+ g.precontrol((Int) 1),g.point((Int) 1),Min,Max);
+#endif
+ return true;
+}
+
+void drawPath3::render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh)
+{
+#ifdef HAVE_GL
+ if(invisible) return;
+
+ setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0);
+
+ setMaterial(material1Data,drawMaterial1);
+
+ bool offscreen;
+ if(billboard) {
+ drawElement::centerIndex=centerIndex;
+ BB.init(center);
+ offscreen=bbox2(Min,Max,BB).offscreen();
+ } else
+ offscreen=bbox2(Min,Max).offscreen();
+
+ if(offscreen) { // Fully offscreen
+ R.Onscreen=false;
+ R.data.clear();
+ R.notRendered();
+ return;
+ }
+
+ triple controls[]={g.point((Int) 0),g.postcontrol((Int) 0),
+ g.precontrol((Int) 1),g.point((Int) 1)};
+ triple *Controls;
+ triple Controls0[4];
+ if(billboard) {
+ Controls=Controls0;
+ for(size_t i=0; i < 4; i++)
+ Controls[i]=BB.transform(controls[i]);
+ } else {
+ Controls=controls;
+ if(!remesh && R.Onscreen) { // Fully onscreen; no need to re-render
+ R.append();
+ return;
+ }
+ }
+
+ double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+
+ R.queue(controls,straight,size3.length()/size2);
+#endif
+}
+
+drawElement *drawPath3::transformed(const double* t)
+{
+ return new drawPath3(t,this);
+}
+
+bool drawNurbsPath3::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ out->addCurve(degree,n,controls,knots,color,weights);
+
+ return true;
+}
+
+// Approximate bounds by bounding box of control polyhedron.
+void drawNurbsPath3::bounds(const double* t, bbox3& b)
+{
+ double x,y,z;
+ double X,Y,Z;
+
+ triple* Controls;
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=new triple[n];
+ for(size_t i=0; i < n; i++)
+ Controls[i]=t*controls[i];
+ }
+
+ boundstriples(x,y,z,X,Y,Z,n,Controls);
+
+ b.add(x,y,z);
+ b.add(X,Y,Z);
+
+ if(t == NULL) {
+ Min=triple(x,y,z);
+ Max=triple(X,Y,Z);
+ } else delete[] Controls;
+}
+
+drawElement *drawNurbsPath3::transformed(const double* t)
+{
+ return new drawNurbsPath3(t,this);
+}
+
+void drawNurbsPath3::ratio(const double* t, pair &b, double (*m)(double, double),
+ double, bool &first)
+{
+ triple* Controls;
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=new triple[n];
+ for(size_t i=0; i < n; i++)
+ Controls[i]=t*controls[i];
+ }
+
+ if(first) {
+ first=false;
+ triple v=Controls[0];
+ b=pair(xratio(v),yratio(v));
+ }
+
+ double x=b.getx();
+ double y=b.gety();
+ for(size_t i=0; i < n; ++i) {
+ triple v=Controls[i];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ }
+ b=pair(x,y);
+
+ if(t != NULL)
+ delete[] Controls;
+}
+
+void drawNurbsPath3::displacement()
+{
+#ifdef HAVE_GL
+ size_t nknots=degree+n+1;
+ if(Controls == NULL) {
+ Controls=new(UseGC) GLfloat[(weights ? 4 : 3)*n];
+ Knots=new(UseGC) GLfloat[nknots];
+ }
+ if(weights)
+ for(size_t i=0; i < n; ++i)
+ store(Controls+4*i,controls[i],weights[i]);
+ else
+ for(size_t i=0; i < n; ++i)
+ store(Controls+3*i,controls[i]);
+
+ for(size_t i=0; i < nknots; ++i)
+ Knots[i]=knots[i];
+#endif
+}
+
+void drawNurbsPath3::render(double, const triple&, const triple&,
+ double, bool remesh)
+{
+#ifdef HAVE_GL
+ if(invisible) return;
+
+// TODO: implement NURBS renderer
+#endif
+}
+
+bool drawPixel::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ out->addPoint(v,color,width);
+
+ return true;
+}
+
+bool drawPixel::write(jsfile *out)
+{
+#ifdef HAVE_LIBGLM
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,color.A);
+ setcolors(false,color,color,Black,1.0,0.0,0.04,out);
+
+ out->addPixel(v,width,Min,Max);
+#endif
+ return true;
+}
+
+void drawPixel::render(double size2, const triple& b, const triple& B,
+ double perspective, bool remesh)
+{
+#ifdef HAVE_GL
+ if(invisible) return;
+
+ RGBAColour Black(0.0,0.0,0.0,color.A);
+ setcolors(false,color,color,Black,1.0,0.0,0.04);
+
+ setMaterial(material0Data,drawMaterial0);
+
+ if(bbox2(Min,Max).offscreen()) { // Fully offscreen
+ R.data.clear();
+ return;
+ }
+
+ R.queue(v,width);
+#endif
+}
+
+drawElement *drawPixel::transformed(const double* t)
+{
+ return new drawPixel(t*v,p,width,KEY);
+}
+
+} //namespace camp