Perspective projection

Hello,

I'm trying to make a perspective projection with the HLR algorithms. First, I define the position of the camera in the view and establish the projection type as Graphic3d_Camera::Projection_Perspective. Then I use a Prs3d_Projector to define the projection with the params predefined in the view. Afterwards, I apply the HLR algorithm and display the VCompound and OutLineVCompound shapes. The problem is that the VCompoud is well computed but the OutlineVcompund don't. You can see it in the attached file (perspective_projection.png). However, if I try to make a orthographic projection the result is good for both shapes (see orthographic_projection.png). Am I doing anything wrong?Or it could be a bug in the software? 

        aView->SetBackgroundColor(Quantity_NOC_GRAY20);
        aView->Camera()->SetCenter(centre);      
        aView->Camera()->SetDirection(gp_Dir (-1.,0., 0.));
        aView->Camera()->SetDistance(300.0);
        aView->Camera()->SetProjectionType(Graphic3d_Camera::Projection_Perspective);
        aView->Redraw();

        Standard_Real aProjVecX, aProjVecY, aProjVecZ;
        aView->Proj(aProjVecX, aProjVecY, aProjVecZ);

        Standard_Real aUpX, aUpY, aUpZ;
        aView->Up(aUpX, aUpY, aUpZ);

        Standard_Real aPntX , aPntY , aPntZ ;
        aView->At(aPntX,aPntY,aPntZ);

        Standard_Boolean IsPerspective = (aView->Type() == V3d_PERSPECTIVE);
        // create a projector object
        Handle(Prs3d_Projector) Projector = new Prs3d_Projector(IsPerspective, 300.0,
                aProjVecX, aProjVecY, aProjVecZ, aPntX, aPntY, aPntZ, aUpX, aUpY, aUpZ);

        gp_Pnt At(aPntX, aPntY, aPntZ);
        gp_Dir Zpers(aProjVecX, aProjVecY, aProjVecZ);
        gp_Dir Ypers(aUpX, aUpY, aUpZ);
        gp_Dir Xpers = Ypers.Crossed(Zpers);
        gp_Ax3 NewCoordSystem(At, Zpers, Xpers);
        gp_Ax3 CurrentCoordSystem(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
        gp_Trsf Trsf;
        Trsf.SetDisplacement(CurrentCoordSystem, NewCoordSystem);

        HLRAlgo_Projector aProjector = Projector->Projector();
        TopLoc_Location aLoc(Trsf);

        // Build The algorithm object
        Handle(HLRBRep_Algo) myAlgo = new HLRBRep_Algo();
        
        
        myAlgo->Add(result);// Add Shapes into the algorithm
        myAlgo->Projector(aProjector);// define the point of view       
        myAlgo->Update();// Launches calculation of outlines of the shape          
        myAlgo->Hide();// Computes the visible and hidden lines of the shape
                   
        HLRBRep_HLRToShape aHLRToShape(myAlgo);// Build the extraction object

        // extract the results of visible parts of the shape:
        TopoDS_Shape VCompound = aHLRToShape.VCompound();
        //Visible sharp edges, Sharp edges present a C0 continuity
        TopoDS_Shape OutLineVCompound = aHLRToShape.OutLineVCompound();
        //Visible outline edges
                          
        aContext->Erase(anAISShape, Standard_False);
        
        VCompound.Location(aLoc);
        Handle(AIS_Shape) aGraphicShape = new AIS_Shape(VCompound);    
        Handle(Prs3d_LineAspect) lineAspect = new Prs3d_LineAspect (Quantity_NOC_FORESTGREEN, Aspect_TOL_SOLID, 1.5);      
        aGraphicShape->Attributes()->SetWireAspect(lineAspect);
        aContext->Display(aGraphicShape);
            
        OutLineVCompound.Location(aLoc);
        Handle(AIS_Shape) aGraphicShape2 = new AIS_Shape(OutLineVCompound);      
        lineAspect = new Prs3d_LineAspect (Quantity_NOC_CORAL4, Aspect_TOL_SOLID, 1.5);      
        aGraphicShape2->Attributes()->SetWireAspect(lineAspect);
                       
        aContext->Display(aGraphicShape2);

 

I really appreciate your help! I've been struggling with this for days...

Guido van Hilst not specified's picture

Hi Adriana

I do not know if it helps in your case? : I've made some code snippets that shows how to use HLR.

See the c # code snipped here: HiddenLine

Best regards, Guido

Adriana Costas's picture

Hi Guido

Thanks for your prompt answer. Your code snippets could be useful but, if I'm not wrong, you are applying an orthographic projection not a perspective one in that example, which is the case for that I have issues. The problem is that I wasn't able to find not a single example of a perspective projection applying HLR. It seems that the algorithm has some difficulties to compute the projection of the edges in this case. Here I have attached another example, this time is a cube. In this case even the VCompound edges are not well computed.

Regards

Guido van Hilst not specified's picture

Hi Adriana,

Yes, HLR does not seem to work well.
I have now tried to set the focus on the projector, but then you can indeed see a mess.
For the PolyAlgo, I do not see any difference with or without focus?

Maybe send a bug report to OpenCascade?

Best regards, Guido

Adriana Costas's picture

Hi,

Yes, that was what I was watching...so, we can affirm that there is a bug. As for the PolyAlgo, I haven't tried to work with it, I'm not really interested in working with approximations.

Thanks Guido.

Regards,

Guido van Hilst not specified's picture

Yes I really think its a bug.

The strange thing is that if I set the focus to 1,0  would expect no difference from parallel projection? (not sure dough)

I have took a look in de cpp code:  If you use the constructor with focus parameter the perspective is set to true.

I have tried may different focus values and other options but it doesn't make sense.

Guido van Hilst not specified's picture

I have put an issue in mantis bugtracker:

https://tracker.dev.opencascade.org/view.php?id=28780

Adriana Costas's picture

Hello,

Just for information, we were able to fix the bug of the perspective projection. You can find attached the patch file that solves the problem.

Regards.

Attachments: 
Andrey BETENEV's picture

Thank you! The fix has been included in OCCT 7.2.0

Adriana Costas's picture

I don't think that is strange...In fact, I've come to the conclusion that the value with which we define the focus is actually the distance to the vanishing point. So, If you use 1.0 as focus you make a very very small projection and thus,  the greater this value is, the more similar the projection will be to the parallel projection. Does it make sense?