sghr / igeo Goto Github PK
View Code? Open in Web Editor NEWiGeo: Computational Design and 3D Modeling Library for Processing
Home Page: http://igeo.jp
License: GNU Lesser General Public License v3.0
iGeo: Computational Design and 3D Modeling Library for Processing
Home Page: http://igeo.jp
License: GNU Lesser General Public License v3.0
iGeo - Java 3D Modeling Library http://igeo.jp iGeo is free and open source 3D modeling software library in Java for computational design in architecture, product design, interaction design and more. It includes libraries of vector math operations, NURBS curve and surface geometries, polygon meshes, 3D display and navigation and 3D model file I/O. It also has an interface called PiGeon specialized for processing. iGeo 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, version 3. iGeo 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 iGeo. If not, see <http://www.gnu.org/licenses/>.
Hi Satoru,
my compliments for your library! I'm using IGeo to draw Nurbs Curves and then construct a Surface with IG.loft (after a few transformations). I would like to show in the same window two different views of my geometries (IG.top of the curves and IG. perspective of the Surface) and I guess I have to use two different IPanes.
Is it possible to use IGeo GUI with Processing 2.2.1? ( When I try to run a sketch I get the error unexpected token: package in reference to the first line package igeo.gui; )
How can I use the IPanel to get the result I need?
Is there any tutorial about this issue?
Thanks in advance!
Dear @sghr San,
I am trying to understand the logic behind the motion of the particles in your A(g)ntense project.
Based on your (remarkable) tutorials I see that your are probably using a mix of a curl field and an attractor field. However few things still remain unclear to me:
What makes the particles move at the same pace along the Z-axis ?
Finally, how did you smooth out the edges of the triangulated layers ? I tried to apply Laplacian smoothing to an alpha triangulated mesh of a layer but doing so kind of shave the edges and make those points disappear from the mesh. Catmull-Rom splines didn't work either (points are on the edges, not near the edges).
I would really appreciate if you could elaborate on these different steps.
Respectfully,
Under processing software, [Add Library], iGeo is grayed out as it marked as incompatible for Processing 3.5.x. Could we officially submit to Processing to get the compatible version listed? It would make life a lot easier.
Dear Sugihara San,
I would like to apply forces of 2 ICompoundField()
(curl field + attractor field) to a Boid()
object that I've coded myself. This boid has an applyForce()
function where it reads the force value corresponding to its position in the compound field and then add it to its acceleration vector.
def applyForce(self):
curlForce = curl.get(IVec(self.pos.x, self.pos.y, self.pos.z))
curlForce = PVector(curlForce.x(), curlForce.y(), curlForce.z())
attrForce = attr.get(IVec(self.pos.x, self.pos.y, self.pos.z))
attrForce = PVector(attrForce.x(), attrForce.y(), attrForce.z())
self.acc.add(curlForce + attrForce) # simple addition of the 2 forces
Unfortunately, doing so gives me very different results from your original sketch entitled "Swarm Formation by Force Fields".
IGravity(0,0,-2)
in setup()
)I would really appreciate if you could explain how did you mix the curl force and attraction force together to get such a smooth motion.
Respectfully,
solub
Edit: Full script if needed
add_library('peasycam')
add_library('hemesh')
add_library('igeo')
W, H, D, s = 10, 15, 10, 100
N = W*H*D
def setup():
#size(1000, 600, P3D)
fullScreen(P3D)
randomSeed(1008)
strokeWeight(.7)
stroke(60)
noFill()
global curl, attr, boids
cam = PeasyCam(this, 1600)
boids = [Boid() for i in xrange(25)]
curl = ICompoundField()
attr = ICompoundField()
for i in xrange(10):
pt = IRand.pt(W*s*.25, 100, D*s*.25, W*s*.75, H*s, D*s*.75)
curl.add(IPointCurlField(pt, IVec(0, -1, 0)).intensity(-20))
attr.add(IAttractor(pt).intensity(20))
IGravity(0,0,-2)
def draw():
background('#FFFFFF')
translate((-W*s)>>1, (-H*s)>>1, (-D*s)>>1)
# Displaying the random points in the field
pushStyle()
stroke(255, 30, 30)
strokeWeight(8)
for p in curl.pointFields:
point(p.pos().x(), p.pos().y(), p.pos().z())
popStyle()
# Updating boids
for b in boids:
b.render()
b.update()
b.flock()
b.applyForce() #Trying to apply the forces of the compound fields to the boids
class Boid(object):
def __init__(self):
self.pos = PVector(random(W*s), 0, random(D*s))
self.vel = PVector().setMag(3)
self.acc = PVector()
self.radius = 50
self.maxSpeed = 1.5
self.maxForce = .1
self.trail = []
def update(self):
self.pos.add(self.vel)
self.vel.add(self.acc)
self.vel.limit(self.maxSpeed)
self.acc.mult(0)
def applyForce(self):
curlForce = curl.get(IVec(self.pos.x, self.pos.y, self.pos.z))
curlForce = PVector(curlForce.x(), curlForce.y(), curlForce.z())
attrForce = attr.get(IVec(self.pos.x, self.pos.y, self.pos.z))
attrForce = PVector(attrForce.x(), attrForce.y(), attrForce.z())
self.acc.add(curlForce + attrForce)
def flock(self):
count = 0
aVel = PVector() #average velocity
aPos = PVector() #average position
aDif = PVector() #average difference
for b in boids:
d = self.pos.dist(b.pos)
if b != self and d < self.radius:
count += 1
aVel += b.vel
aPos += b.pos
diff = self.pos.copy().sub(b.pos)
aDif += diff.div(d) #inversional to distance (the farther, the lower the magnitude)
if count > 0:
#Alignment
aVel.div(count).setMag(self.maxSpeed) #maxSpeed prevent from steering too hard
alignSteering = aVel.sub(self.vel).limit(self.maxForce)
#Cohesion
aPos.div(count)
coheSteering = aPos.sub(self.pos).setMag(self.maxSpeed).sub(self.vel).limit(self.maxForce)
#Separation
aDif.div(count)
sepaSteering = aDif.setMag(self.maxSpeed).sub(self.vel).limit(self.maxForce)
self.acc.add(coheSteering + sepaSteering) #+ alignSteering # Alignment set to 0 by Sugihara san in his original sketch
def render(self):
pushStyle()
strokeWeight(8)
point(self.pos.x, self.pos.y, self.pos.z)
popStyle()
# Trail
if frameCount%10 == 0:
self.trail.append(PVector(self.pos.x, self.pos.y, self.pos.z))
if len(self.trail) > 0:
for i in xrange(1, len(self.trail)):
line(self.trail[i-1].x, self.trail[i-1].y, self.trail[i-1].z, self.trail[i].x, self.trail[i].y, self.trail[i].z)
Dear @sghr ,
I would like to use some of the classes of IGeo with the P3D
renderer in draw()
, is that possible ?
For instance, could I turn this sketch (IG.GL
with Python mode)...:
add_library('igeo')
def setup():
size(1000,600,IG.GL)
for i in xrange(25):
MyBoid(IRand.pt(-300,-300,0,300,300,0), IRand.pt(-10,-10,-20,10,10,-20))
curl = ICompoundField().target(MyBoid)
attr = ICompoundField().target(MyBoid)
for i in xrange(10):
pt = IRand.pt(-100,-100,-800,100,100,-100)
curl.add(IPointCurlField(pt, IVec(0,0,-1)).intensity(20))
attr.add(IAttractor(pt).intensity(20))
IGravity(0,0,-2)
class MyBoid(IBoidTrajectory):
def __init__(self, p, v):
super(MyBoid, self).__init__(p, v)
self.alignment(0, 0)
self.cohesion(2, 40)
self.separation(4, 50)
self.fric(0.01)
... into something like this (P3D
with draw()
):
add_library('igeo')
def setup():
size(1000,600,P3D)
global boids
boids = [] #appending MyBoid object to a list
for i in xrange(25):
b = MyBoid(IRand.pt(-300,-300,0,300,300,0), IRand.pt(-10,-10,-20,10,10,-20))
boids.append(b)
curl = ICompoundField().target(boids) #???? or something equivalent
attr = ICompoundField().target(boids) #???? or something equivalent
for i in xrange(10):
pt = IRand.pt(-100,-100,-800,100,100,-100)
curl.add(IPointCurlField(pt, IVec(0,0,-1)).intensity(20))
attr.add(IAttractor(pt).intensity(20))
IGravity(0,0,-2)
def draw():
background(255)
for b in boids:
b.update() #???? or something equivalent
point(b.pos().x(), b.pos().y(), b.pos().z())
class MyBoid(IBoidTrajectory):
def __init__(self, p, v):
super(MyBoid, self).__init__(p, v)
self.alignment(0, 0)
self.cohesion(2, 40)
self.separation(4, 50)
self.fric(0.01)
Respectfully,
solub
Thanks for creating this nice library!
Is there any chance to have it updated to support Processing 3?
Hi,
I was wondering if there was a way to display all necessary entry fields for each Igeo Command ?
For example, when scripting on Rhino Python, as soon as we open a bracket following a command, the text editor displays at the bottom what kind of data we re supposed to input. For example for a circle, we need a center and a radius...
Is it possible with IGeo/ Processing ?
Does someone has a tip to work effectively without switching each time to http://igeo.jp/doc/ that contains everything ??
Thank you in advance ?
Hi,
Thanks for this excellent library!
It seems that when exporting geometries as .obj, some ISurface elements don't appear as surfaces in some softwares.
For instance, when I open the geometry exported from igeo_tutorial15_2 in Meshlab (or zbrush), I only get some vertices and no faces. Opening the same obj file in Rhino gives the proper geometry.
It seems that geometries created with IMesh are correctly read by meshlab: for instance, geometries exported from igeo_tutorial8_3 appear as proper surfaces (not just vertices).
Hi,
Is it possible to write openGL code in igeo ? The javadoc refers to a GL1 renderer :
'Processing Graphics using OpenGL to be put in size() method in Processing '
Is there an example of how to use it somewhere ?
thanks!
When using the uv() function to project a point (IVec) on to a surface, there seem to be a problem if the surface is closed (like a tube or a cylinder).
A picture is worth a thousand words so :
The black line is where the UV coordinates wrap back, the red dots are projected through the yellow arrow to the magenta points. Around the seam, the projected points end up on the seam instead of their normal place.
Also, every 10 points or so, the projection is a bit off. Dunno if it's related or not...
I hope this can help correcting it !
I have five ICurves and I'm using them to generate a surface with ILoft. The surface I get isn't able to approximate the curves as I need, it seems like a Rhino Loose Loft, so I was wondering if it's possible to get the same result of Rhino Normal Loft, with the surface passing through the curves in their exact position.
I tried also to use ICurve control points to create an ISurface with a bidimensional array IVec [][], but I get the same result. Is there a way to generate the surface that I need?
I tried to increase the degree in both the methods, but the best surface I'm able to draw was with degree 2 in both directions.
Another doubt is if there is a function to adjust curve seam.
Thanks in advance for your kind help!
How to I access the field strength of an IAttractorField? Using the get() method doesn't seem to work. It is zero strength at every point.
import processing.opengl.;
import igeo.;
IAttractor attr = null;
void setup()
{
size(480, 360, IG.GL);
attr = new IAttractor(0,0,0, 20.f).noDecay();
IVecI f = attr.get(new IVec(20, 30, 40));
println(f);
}
Output:
(0.0,0.0,0.0)
Dear @sghr,
Folks on the Processing forum (me included) have a hard time figuring out how to port your sketch on Particle-based Branching with Spring Force to Python.
It seems you are putting an instruction as an argument inside of super()
when initializating the LineAgent
constructor:
super(parent.pos().cp(dir))
on line 7 of the snippet below
class LineAgent extends IParticle{
LineAgent parent;
boolean isColliding;
IVec dir;
LineAgent(IParticle parent, IVec dir){
super(parent.pos().cp(dir)); // <-- here !
if(parent instanceof LineAgent){
this.parent = (LineAgent)parent;
}
isColliding=false;
hide(); // hide point
this.dir = dir;
fric(0.2);
}
How would that translate in Python mode ?
--Failed attempt--
class LineAgent(IParticle):
def __init__(self, parent, dir):
super(LineAgent, self).__init__(parent, dir) #or IParticle.__init__(self, parent, dir)
#parent.pos().cp(dir) #<-- WHERE should this go ?
if isinstance(parent, LineAgent):
self.parent = parent
self.isColliding = False
self.dir = dir
self.hide()
self.fric(0.2)
No matter what we try, we always end-up with an annoying 'instancemethod' object has no attribute 'pos'
error.
-- Full sketch --
add_library('igeo')
def setup():
size(480, 360, IG.GL)
IG.bg(1.0)
IG.top()
for i in xrange(4):
LineAgent(IParticle(IRand.pt(-40,-40,0,40,40,0)).hide().fric(0.2), IRand.dir(IG.zaxis).len(2))
for i in xrange(20):
IAttractor(IRand.pt(-200,-200,0,200,200,0)).linear(50).intensity(-30)
class LineAgent(IParticle):
def __init__(self, parent, dir):
super(LineAgent, self).__init__(parent, dir)
#parent.pos = parent.pos().cp(dir) #<-- WHERE should this go ?
if isinstance(parent, LineAgent):
self.parent = parent
self.isColliding = False
self.dir = dir
self.hide()
self.fric(0.2)
def interact(self, agents):
if self.time() == 0:
for agent in agents:
if isinstance(agent, LineAgent) and agent != self:
# ERROR below --> attributeError: 'instancemethod' object has no attribute 'pos'
# more specifically: 'self.parent' has no attribute 'pos'
if agent.parent != None and agent.pos().dist(self.pos()) < self.pos().dist(self.parent.pos())*2:
intxn = IVec.intersectSegment(agent.parent.pos(), agent.pos(), self.parent.pos(), self.pos())
if intxn != None and not intxn.eq(self.parent.pos()) and not agent.isColliding:
self.isColliding = True
return
def update(self):
if self.isColliding:
self.del()
else:
if self.time() == 0 and self.alive():
if self.parent != None and self.parent.alive():
ln = ISpringLine(self, self.parent, 100)
t = -cos(IG.time()*.015) * .5 + .5
ln.hsb(.7 - t*.2, 1, .8 - t*.2, .5)
if self.parent.parent != None and self.parent.parent.alive():
st = IStraightenerCurve(self, self.parent, self.parent.parent).tension(100)
st.hsb(.7 - t*.2, 1, .8 - t*.2, .5)
if self.time() == 4:
dir2 = self.dir.cp()
angle = PI*.12
if IRand.pct(50):
self.dir.rot(angle)
dir2.rot(-angle)
else:
self.dir.rot(-angle)
dir2.rot(angle)
LineAgent(self, self.dir)
if IRand.pct(20):
LineAgent(self, dir2)
l = LineAgent(self, dir2)
While working with data extracted from images I noticed a strange mesh behavior for ISurface. Ouliers occur and the contours flicker. Probably some overflow in the rendering part??? I have isolated the bug to be easily reproducable (see code below). Look at the lower left corner of the generated mesh. It occurs with uSize >= 63 for vSize = 4 and with increasign vSize the uSize threshold for the bug to be visible decreases. Can you please have a look on it and possibly fix it?
int uSize = 63;
int vSize = 4;
IVec4[][] controlPoints = new IVec4[uSize][vSize];
for(int i = 0; i < uSize; ++i)
for(int j = 0; j < vSize; ++j)
controlPoints[i][j] = new IVec4(i, i, j); //the bug is also visible for i,i+j,j i,i*j,j i,i/(j+1),j etc.
new ISurface(controlPoints, 3, 3).clr(1,.5,1);
Hi Satoru, long time no see! I was excited to see you post the iGeo library, it looks like it has a ton of useful and exciting features.
The web tutorials on your site are very helpful in understanding the functions the library offers, but I wonder if it would not be more convenient to offer them as downloadable examples (as PDE files)? Right now users have to copy and paste from the web into Processing, which seems awkward compared to navigating them as a folder structure inside Processing. Just a thought.
Again, thank you for creating the library and posting the code on GitHub. The projects on the Gallery page on your site already look more advanced than most efforts in Processing 3D.
Is there a way to select objects by mouse in 3D view?
I am pasting the sketch code from these examples into the latest version of Processing: http://igeo.jp/tutorial/50.html
IFieldVisualizer doesn't render anything for the early simple examples such as:
import processing.opengl.;
import igeo.;
size(480, 360, IG.GL);
new IAttractor(-50,0,0).intensity(10).clr(1.0,0,0);//attractor
new IAttractor(50,0,0).intensity(-10).clr(0,0,1.0);//repulsion
// last 3 inputs are sample number in x, y, z.
new IFieldVisualizer(-100, -50, 0, 100, 50, 0, 40, 20, 1);
I am fairly new to both Processing and iGeo and for the life of me I cannot figured out how to take a simple screenshot of the canvas properly.
Take for instance the code below: I am creating a bunch of random points one by one on XY plane.
At each update iteration/duration I want to capture a screenshot to make a gif file afterward.
When I run the code, I will either get the "com.jogamp.opengl.GLException: GL-Error 0x502" or the generated screenshots will be all black with no objects in it.
I can, as a last resort, create a keyPressed function with the save/saveFrame method inside to capture screenshot on key press and that works, but it seems extremely counter intuitive. What am I doing wrong? What is the proper method to capture screenshot sequentially with iGeo?
I am using iGeo 0.9.4.1 and Processing 3.5.4 on Python mode.
the code:
add_library('igeo')
def setup():
size(480,360,IG.GL)
IG.bg(1)
IG.persTarget()
IG.duration(20)
rPoint = RandPoint(0,200)
class RandPoint(IAgent):
points = []
frame = 0
def __init__(self, mm, mx):
self.min = mm
self.max = mx
def update(self):
min = self.min
max = self.max
self.points.append(IPoint(IRand.get(min, max), IRand.get(min, max),0).clr(IRand.clr()))
self.frame += 1
print('add point number {}'.format(self.frame))
save('ss'+str(self.frame)+'.jpg')
Hi! I came across your library via http://processing.org/reference/libraries/, as I'm looking for a library that will let me import & manipulate NURBS. I downloaded the latest version (beta 0.9.0.4) here: http://igeo.jp/igeo.zip, unzipped it and added it to my ~/Sketchbook/libraries/ directory. It shows up under Sketch > Import Library > iGeo, so I figure the library was installed properly.
I followed your tutorial and proceeded to import the library, as well as processing.opengl.*, but when I try to compile with nothing more than these 2 imports and a size statement:
import processing.opengl.*;
import igeo.*;
size(640, 480, IG.GL);
I get the following error:
NoSuchFieldError: You may be using a library that's incompatible with this version of Processing.
java.lang.NoSuchFieldError: canvas
at igeo.p.PIGraphicsGL2.initPrimary(PIGraphicsGL2.java:156)
at processing.opengl.PGraphicsOpenGL.requestDraw(PGraphicsOpenGL.java:1600)
at processing.core.PApplet.run(PApplet.java:2177)
at java.lang.Thread.run(Thread.java:744)
What am I doing wrong? Can you help me? Your library is exactly what I'm looking for if only I could get it running, so I'd be much obliged.
Cheers
Is there a class missing IParticleOnSurface in the library as I am not able to run the Tutorials Agent-Based Panelization Algorithm???
Hi Satoru,
my compliments for this cool library iGeo. I'm using it for developing an Aircraft Design tool that soon will go open source.
Is there a way to show some Processing primitives into an iGeo IPanel?
For instance, the box primitive shown here:
http://processing.org/examples/primitives3d.html
Thanks,
Agostino De Marco
University of Naples Federico II, Italy
IFieldVisualizer.fixLength(False) does not work in PythonMode
Hi, I am new to this great library.
Currently, I want to get sampling points evenly on the ICurveGeo.
I have tried to use pt(double u) function and got some points based on evenly sampling the u coordination. I just wonder if there is a way to let the user sampling points based on the arc-length of the curve, so the user can get those sampling points accurately.
Thanks a lot.
Again great library for 3D modeling in Java
When for some reason I extend IGraphicObject I can access all properties of IGraphicObject from my extended class (eg. visible, parent)... except one : color.
This property collide in some way with processing. So so it will not compile if i refer to this.color.
Is it possible for you to rename it to icolor or something like that
Thanks a lot
Dear @sghr San,
Your library is very good, it's like magic for creating 3D models using Java.
Currently, I am facing a problem (maybe it's my misunderstanding of the usage).
I tried to sweep two curves. Everything is OK.
But when I sweep two straight lines, which are generated by ICurveGeo sharing the same z-coordinate,
I got some error messages like the surface is invalid. I provide the following code, hope you can reproduce it.
`import processing.opengl.;
import igeo.;
size(480, 360, IG.GL);
IVec[] cptsU = new IVec[5];
cptsU[0] = new IVec(0, 0, 50);
cptsU[1] = new IVec(60, 0, 50);
cptsU[2] = new IVec(120, 0, 50);
cptsU[3] = new IVec(180, 0, 50);
cptsU[4] = new IVec(240, 0, 50);
ICurveGeo m_curveU = new ICurveGeo(cptsU, 3, false);
IVec[] cptsV = new IVec[5];
cptsV[0] = new IVec(100, 0, 10);
cptsV[1] = new IVec(100, 50, 10);
cptsV[2] = new IVec(100, 100, 10);
cptsV[3] = new IVec(100, 150, 10);
cptsV[4] = new IVec(100, 200, 10);
ICurveGeo m_curveV = new ICurveGeo(cptsV, 3, false);
IG.sweep(m_curveU, m_curveV);
`
In addition, if I misunderstood IG.sweep, can you correct me, or guide me another way to achieve a surface by sweeping two straight lines?
Sincerely!
Is it possible to bring back the shader/LoadShader etc. functionality from Processing 2?
I need the shader for a depth of field effect. There are no erros using this functions, but no result is displayed.
In PIGraphicsGL2 the Processing draw() function is overwritten to execute drawIG(). Can I start there? How?
Thanks in advance
Carsten Tigges
Is there currently a way to represent a closed object in iGeo? For example, if I want to extrude a surface? I saw iBox, which looks like one representation, but I didn't see anything more general. I suppose meshes can be closed?
I am having troubles understanding how to use 3d Delaunay class in IGEO for processing.
I Understand the part of creating tetrahedrons, but I can not figure it out after that. Also, I would like to ask why is processing running much slower once delaunay class is used?
Hi,
I'm currently training on IGeo and reached the last tutorial of this page http://igeo.jp/tutorial/36.html (updating Agents using vectors).
I was wondering why do we need a for loop in the following :
import processing.opengl.;
import igeo.;
void setup(){
size(480, 360, IG.GL);
IG.duration(250);
int num = 40;
float inc = 2PI/num;
for(int i=0; i < num; i++){
new MyAgent(IG.v(40cos(iinc), 40sin(iinc), 0),
IG.v(5cos((i+6)*inc), sin((i+6)*inc), 0));
}
}
the IG.duration is setting up how many times the action is done, what is the role of that For Loop and the variable "int num = 40" ?
Does it mean there will be 40 initial instances starting at 40 different positions as the i is implemented in the vectors ?
Thanks in advance,
Gari,
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.