sebleedelisle / ofxLaser

An openFrameworks addon for controlling multiple lasers.
Mozilla Public License 2.0
258 stars 32 forks source link

Seeking a suggestion of how feed the shapes into syphon #36

Closed eighteight closed 2 years ago

eighteight commented 2 years ago

I am toying with the idea of combining laser and video–projection whereby the laser outlines would be mapped together the filled video shapes onto the same surface. Both laser and video projectors must take into account the image warping produced by an operator in the ofxLaser app, which uses svg files as input. Laser would produce outlines, projector would produce the filled shapes, which would be adjusted perspective-wise by the external application receiving the syphon input from the ofxLaser app.

@sebleedelisle could you suggest architecturally where I could plug in syphon server to stream the warped shapes out?

Thanks

sebleedelisle commented 2 years ago

If it were me I would render the finished manipulated shapes into ofxLaser - you can use the zone output settings to fix the perspective for the laser at least. Then I would render them again into an FBO. In the past when I have done this, I have put the output onto a different screen space and outputted that to a projector (using a custom perspective correction system that I can dig out if you like). But I don't think it'd be any different sending it to syphon if you prefer. Does that answer your question?

eighteight commented 2 years ago

I am drawing filled shapes in ofxLaserManagerBase::drawPoly by adding the code between BEGIN/END FILL THE POLYLINE like so:

void ManagerBase::drawPoly(const ofPolyline & poly, const ofColor& col, string profileName, float brightness){

    // quick error check to make sure our line has any data!
    // (useful for dynamically generated lines, or empty lines
    // that are often found in poorly compiled SVG files)

    if((poly.size()==0)||(poly.getPerimeter()<0.01)) return;

    ofPolyline& polyline = tmpPoly;
    polyline = poly;

    for(glm::vec3& v : polyline.getVertices()) {
        v = gLProject(v);
    }

    //BEGIN FILL THE POLYLINE
    ofBeginShape();
        for( int i = 0; i < polyline.getVertices().size(); i++) {
            ofVertex(poly.getVertices().at(i).x, poly.getVertices().at(i).y);
        }
    ofEndShape();
    //END FILL THE POLYLINE

    Polyline* p =new ofxLaser::Polyline(polyline, col*brightness, profileName);
    p->setTargetZone(targetZone); // only relevant for OFXLASER_ZONE_MANUAL
    shapes.push_back(p);    
}

As far as I understand the call to gLProject(v); should take care of warping, however the output I get is not warped:

Screenshot 2022-05-10 at 2 37 13 PM

Once I am able to apply the warp to these filled shapes, I am going to feed them into syphon via FBO.

However, what am I doing wrong not being able to warp the added shapes?

Thanks a lot.

sebleedelisle commented 2 years ago

I'm not sure exactly what you're trying to do but I would really avoid changing the code within ofxLaser::Manager.

The zone warping within ofxLaser is designed to perspective correct output from the lasers. Are you using it to warp the output as a creative effect? If yes then I would do that separately and before you send it to the laser.

Hope this helps!

eighteight commented 2 years ago

I'd like to take the warped shape, SEBLEE, for example's sake, (like in the Left Lower Corner in the picture above), fill it (using ofBeginShape/ofEndShape), and send it to syphon. I don't think you can call it a "creative effect" –– it is just a filled shape which has been warped precisely as in the interface above.

If I read you right, this should happen in the "zone warping within ofxLaser" –– could you specify that place in terms of specific file and method?

Thanks!

sebleedelisle commented 2 years ago

I'm sorry I don't think I understand. Why are you warping the output like that in the lower left? Is it to be mapped onto 2 walls? If yes, then you would need to do that separately for the bitmap images and the laser images. There is no easy way to take the warped output that goes to the lasers and convert it back into shapes that can be rendered into a bitmap. Hope this helps, and sorry if I am misunderstanding.

On Tue, 10 May 2022 at 13:47, eight_io @.***> wrote:

I'd like to take the warped shape, SEBLEE, for example's sake, (like in the Left Lower Corner in the picture above), fill it (using ofBeginShape/ofEndShape), and send it to syphon. I don't think you can call it a "creative effect" –– it is just a filled shape which has been warped precisely as in the interface above.

If I read you right, this should happen in the "zone warping within ofxLaser" –– could you specify that place in terms of specific file and method?

Thanks!

— Reply to this email directly, view it on GitHub https://github.com/sebleedelisle/ofxLaser/issues/36#issuecomment-1122346017, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA3CESPVKOELCMWVSW2MWTVJJLF7ANCNFSM5VIVGTTQ . You are receiving this because you were mentioned.Message ID: @.***>

eighteight commented 2 years ago

Lower left corner warp above is just a random example –– I am preparing to be ready to project laser line output (adding a video fill) on arbitrary surfaces (could be two walls, or a slanted wall or three walls). So I figure, if ofxLaser already gives me the warp of the laser lines, I just need to apply this warp to the same lines rendered as filled shapes, before sending these filled shapes to syphon. I don't know how to better describe what I am after

sebleedelisle commented 2 years ago

The warp system in ofxLaser is specifically designed to warp the point stream that is sent to the laser. It's not designed for warping bitmaps so you will need to build a separate system for doing that with a bitmap image.

Either way, you would need two separate processes to warp the laser output and the projector output as the laser and projector will have different positions, and different lens/scanner distortions and it will be impossible to line them up otherwise.

I'm sorry I don't have an easier answer for you but there are a number of openFrameworks addons that can perform perspective undistortion on bitmaps, have a hunt around ofxAddons - good luck!

Kindest, Seb

eighteight commented 2 years ago

@sebleedelisle I dealt with this problem by adding the following method to ofxLaserLaser:

void Laser::drawToSyphon() {

    fbo.begin();
    ofClear(0);
    ofPath path;

    for( int i = 0; i < laserPoints.size(); i++) {
        if(i == 0) {
            path.newSubPath();
            path.moveTo(laserPoints[i] );
        } else {
            path.lineTo( laserPoints[i] );
        }
    }

    path.close();
    path.simplify();
    path.draw();
    fbo.end();
    fbo.draw(0,0);
    syphonServer.publishTexture(&fbo.getTexture());
    //END FILL THE POLYLINE
}

This fills the warped shape, renders it to the fbo, and then fbo is drawn

Screenshot 2022-05-11 at 5 43 52 PM

The fbo's texture, representing the fill of this laser's warped shape is also sent to syphon:

Screenshot 2022-05-11 at 5 43 16 PM

The only issue is that the laserPoints contain some additional (compared to the original SVG) points, which sometime screw the fill.

Could you suggest a cleaner vector of points I could use to get a clean fill?

Thanks!

sebleedelisle commented 2 years ago

I think you’re coding yourself into a corner here. Please see my previous comment for my recommended approach.

eighteight commented 2 years ago

That's the corner I meant to be in:

https://user-images.githubusercontent.com/542368/167911119-79a899a2-4dbb-4c56-a068-833d99134a1c.mov

Could you suggest how to get a cleaner version of laserPoints to get a clean fill?

Thanks!