Computer aided Designs

@dave1707 nice! if you could implement true 3d tubes that would be great- it is something i’ve wanted for a long time!

@piinthesky You can create 3D tubes. Here an example of a square tube. You could probably create a circular tube, but I didn’t want to spend that much time trying to do it.

displayMode(FULLSCREEN)

function setup()
    assert(craft, "Please include Craft as a dependency")
    assert(OrbitViewer, "Please include Cameras as a dependency")        
    scene = craft.scene()
    skyMaterial=scene.sky.material
    skyMaterial.sky=color(158, 202, 223, 255)
    skyMaterial.horizon=color(105, 188, 227, 255)
    scene.sun.rotation=quat.eulerAngles(45,45,-80)
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 20, 0, 700)
    v.ry=15
    v.rx=10
    createTube()
end

function draw()
    update(DeltaTime)
    scene:draw() 
end

function update(dt)
    scene:update(dt)
end

function createTube()
    pt=scene:entity()
    pt.model = craft.model.cube()
    pt.model.positions=
    {   vec3(-3,-3,40),vec3(-3,3,40),vec3(-3,3,0),vec3(-3,-3,0),
        vec3(3,-3,40),vec3(3,3,40),vec3(3,3,0),vec3(3,-3,0),
        vec3(-3,-3,40),vec3(-3,3,40),vec3(-3,3,0),vec3(-3,-3,0),
        vec3(3,-3,40),vec3(3,3,40),vec3(3,3,0),vec3(3,-3,0),
    }    
    pt.model.indices=
    {   1,3,4, 1,2,3, 8,7,5, 7,6,5,  
        12,11,9, 11,10,9, 13,15,16, 13,14,15,
        3,2,6, 3,6,7, 5,1,4, 8,5,4,
        14,10,11, 15,14,11, 12,9,13, 12,13,16,
    }
    pt.material = craft.material("Materials:Specular")    
    pt.material.map = readImage("Blocks:Gravel Stone")
end

@piinthesky I did a little more work on the 3D tube. Here’s a better example. You can change the number of sides to alter the roundness of the tube. You can also change the length len of the tube and the diameter dia.

displayMode(FULLSCREEN)

function setup()
    assert(craft, "Please include Craft as a dependency")
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
    scene = craft.scene()
    skyMaterial=scene.sky.material
    skyMaterial.sky=color(158, 202, 223, 255)
    skyMaterial.horizon=color(105, 188, 227, 255)
    scene.sun.rotation=quat.eulerAngles(45,90,80)
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 250, 0, 700)
    v.rx=10
    v.ry=-20
    len=200
    dia=10
    sides=20
    pos={}
    -- calculate vertex values
    for z=0,359,360/sides do
        x=math.sin(math.rad(z))*dia
        y=math.cos(math.rad(z))*dia
        table.insert(pos,vec3(x,y,0))
        table.insert(pos,vec3(x,y,len))
    end
    ind={}
    v=0
    ss={1,2,4,1,4,3,4,2,1,3,4,1}
    -- calculate indices values
    for z=1,#pos/2 do
        for w=1,#ss do
            val=ss[w]+v
            if val>#pos then
                val=val-#pos
            end
            table.insert(ind,val)
        end
        v=v+2
    end 
    col={}
    for z=1,#pos do
        table.insert(col,color(math.random(255),math.random(255),math.random(255)))
    end
    createTube()
end

function draw()
    update(DeltaTime)
    scene:draw() 
    fill(255)
    text("Slide your finger around the screen to rotate the object.",WIDTH/2,HEIGHT-30)
    text("Use two fingers to zoom in, out, or move the object.",WIDTH/2,HEIGHT-60)
end

function update(dt)
    scene:update(dt)
end

function createTube()
    pt=scene:entity()
    pt.model = craft.model.cube()
    pt.model.positions=pos
    pt.model.indices=ind
    pt.model.colors=col
    pt.material = craft.material("Materials:Basic")    
end

thanks @dave1707 - very nice! Could be interesting to combined it with your bezier curves program to have 3d tubes that follow the path of the bezier (or a list of predefined 3d coordinates).

@piinthesky I don’t know how much trouble there would be connecting the tubes. Maybe I’ll have to try.

I have quite a bit of code for constructing tubes along paths. You can see an example at https://youtu.be/XrseM3H5Y8k

Most of the necessary code is actually in the Roller Coaster project as that works out all the directions (normal and binormal) along the path which are needed to make the segments fit together. Once that’s in place, making the tube fit is quite straightforward.

@LoopSpace Nice Example. I looked thru the Roller Coaster Example, but there’s a lot of code to go thru. Do you have anything that works with Craft.

I’ve extracted what I could. It needs the PseudoMesh and MeshExt code from my Graphics Libraray. The code would be slightly simpler if using the VecExt code from my Mathematics Library but I’ve copied the relevant stuff in.

function setup()
    assert(craft, "Please include Craft as a dependency")
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")

    scene = craft.scene()
    scene.camera:add(OrbitViewer)
    local track = scene:entity()
    local p = f(0)
    local np,nt,nq,ax,ang

    local t = (f(.001) - f(-.001))/0.002
    local it = t
    local nml = vec3(1,0,0)
    local pts = {{p,it,nml}}
    for k=1,100 do
        np = f(k/100*2*math.pi)
        nt = (f(k/100*2*math.pi+.001) - f(k/100*2*math.pi-.001))/0.002
        ax = t:cross(nt)
        ang = math.asin(ax:len()/(t:len()*nt:len()))
        nml = nml:rotate(ang,ax)
        
        table.insert(pts,{np,nt,nml})
        t = nt
        p = np
    end
    local __track = PseudoMesh()
    local ends = 1
    for k=1,100 do
        if k == 100 then
            ends = 2
        end
        __track:addCylinder({
            startCentre = pts[k][1],
            startWidth = pts[k][3],
            startHeight = pts[k][2]:cross(pts[k][3]):normalize(),
            endCentre = pts[k+1][1],
            endWidth = pts[k+1][3],
            endHeight = pts[k+1][2]:cross(pts[k+1][3]):normalize(),
            ends = ends,
            faceted = false,
            size=50
        })
        ends = 0
    end
    track.model = __track:toModel()
    track.material = craft.material("Materials:Standard")
end

function draw()
    background(40,40,50)
    update(DeltaTime)
    scene:draw()
end

function update(dt)
    scene:update(dt)
end

local mt = getmetatable(vec3())
mt.rotate = function(v,a,u)
    u = u or vec3(1,0,0)
    u = u:normalize()
    local x = v - v:dot(u)*u
    local y = u:cross(x)
    return v - x + math.cos(a)*x + math.sin(a)*y
end

function f(t)
    local r,h=5,5
    return vec3(r*math.cos(t),r*math.sin(t),h*t)
end

The way it works is to create a table of points along the path (this version uses the parametrisation - the one used in the Roller Coaster uses arc length but that’s harder to compute). It also computes the tangent vector at each point, and it keeps track of a normal vector (the method by which it does that is slightly complicated). These vectors can then be used to construct a cylindrical segment from each point to the next with axis along the curve. The cylindrical segments can have end faces not parallel so it can cope easily with the curvature of the curve.

I used a helix rather than a bézier curve for no good reason.

@Loopspace - problem with cimport, which can’t find in the code above (apart from the call) or in the libraries you’ve mentioned. Is it part of Craft code?

Craft and Cameras are used as dependencies.

@Bri_G add the pseudomesh and meshext classes in your tabs, then comment out the cmodule line. Thanks @LoopSpace works great!..

https://youtu.be/o3_dpucB1zY

@Bri_G Sorry, the line with cimport should have been removed before pasting. I use @toadkick’s cmodule for side-loading tabs from other projects. I meant to remove all references to it when I copied the code here but one slipped through, sorry.

@piinthesky thanks for posting the video! Do feel free to ask anything about the code.

Hi guys, sorry to be a pest on this but - I was using PseudoMesh an MeshExt and I even added the VecExt to try to get it working. Commented out the cimport but still no joy. Removed VecExt then moved PseudoMesh tab to left then no errors, but just a black screen. Left for about 30 secs still no image. I’m missing something.

@Bri_G I loaded it and it works fine. Image pops up in about a second. I reloaded the code @LoopSpace posted above. I put PseudoMesh in a tab called PseudoMesh. I put MeshExt in a tab called MeshExt. When I ran it I got an error and I think I had to take the local off of PseudoMesh = class(). Post again if it doesn’t work and I’ll delete it and try loading all of it again and see what happens.

Can’t understand this, recouped all three tabs, with and without local on the PseudoMesh = class(). Bother dependencies on and main tab in middle. Just a black screen.

Have just updated to iOS 11.26 - no effect.

I noticed that Codea was in the update store yesterday, I didn’t install and now it’s gone. Will try to re-install Codea and see if that resolves it

@Simeon - just noticed a funny on my iPad, held my touch on Codea icon and it brought up several images from my Dropbox, pressed see more and it showed more images. This occurred after doing a backup to my Dropbox.

Can’t understand this, repasted all three tabs, with and without local on the PseudoMesh = class(). Bother dependencies on and main tab in middle. Just a black screen.

Have just updated to iOS 11.2.6 - no effect.

I noticed that Codea

@Bri_G I loaded everything again and it worked. So here’s the steps I took.

  1. Copied the code from above and pasted it into a new project.
  2. Went to the Graphics Library shown above and opened PseudoMesh.lua
  3. Selected RAW and copied the code.
  4. Created a new blank file (tab) and named it PseudoMesh
  5. Pasted the PseudoMesh code into the tab
  6. Went to the Graphics Library and opened MeshExt.lua
  7. Selected RAW and copied the code
  8. Created a new blank file and named it MeshExt
  9. Pasted the MeshExt code into the tab
  10. Ran the code.
  11. Got error for Craft and Cameras, included them
  12. Got error for PseudoMesh, removed local from PseudoMesh=class()
  13. Ran program and image appeared in about 1 second.

If no errors and nothing shows, put 2 fingers on the screen and move them together. Maybe the image is off to one side and pinching the screen will move the camera farther from the image and maybe it will show.

@Bri_G As for long pressing on the Codea icon, I mentioned that in the Codea 103 discussion. For me, it shows files from the Files app.

Here’s the code in one file, with most of the unnecessary stuff removed.

https://gist.github.com/loopspace/094ef466b0066fe3c5969a9960c3e694

@Loopspace, @Dave1707 - thanks for the help on this, uninstalled Codea then reinstalled and synced my Dropbox - an hour later followed @Dave1707 stepwise breakdown - still got an error, moved PseudoMesh before Main and lost error but just a black screen - just like before.

Copied @Loopspace code across and ran perfectly - very impressive and very fast. Thank you.

On an aside, after dumping all my code I started to set up collections to tidy up the code when I re-install all projects and noted @Simeon has added collapsible collections - thank you.

Are these structures retained in a backup?