1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-05 11:24:17 +03:00
occt/src/Draw/Draw_Viewer.cxx
abv ed4415982c 0024624: Lost word in license statement in source files
License statement text corrected; compiler warnings caused by Bison 2.41 disabled for MSVC; a few other compiler warnings on 54-bit Windows eliminated by appropriate type cast
Wrong license statements corrected in several files.
Copyright and license statements added in XSD and GLSL files.
Copyright year updated in some files.
Obsolete documentation files removed from DrawResources.
2014-03-25 16:38:55 +04:00

2070 lines
55 KiB
C++

// Created on: 1992-04-06
// Created by: Remi LEQUETTE
// Copyright (c) 1992-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// Updated by GG Tue Oct 22 16:22:10 1996
// reason : Try to compress the pixel image
// in PseudoColor 8 planes format
// see : SaveView(filename)
#include <Draw_Viewer.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Draw_Window.hxx>
#include <Draw_Display.hxx>
#define precpers 0.95
#define ButtonPress 4
#define MotionNotify 6
static const Standard_Real DRAWINFINITE = 1e50;
Standard_EXPORT Standard_Boolean Draw_Bounds = Standard_True;
extern Standard_Boolean Draw_Batch;
const Standard_Integer MAXSEGMENT = 1000;
Segment segm[MAXSEGMENT];
static int nbseg=0;
static Draw_View* curview = NULL;
static Standard_Integer curviewId = 0;
static char blank[2] = "";
static Standard_Real xmin,xmax,ymin,ymax;
static Standard_Boolean found = Standard_False;
static Standard_Integer xpick, ypick, precpick;
static gp_Pnt lastPickP1;
static gp_Pnt lastPickP2;
static Standard_Real lastPickParam;
static Draw_Color highlightcol;
static Draw_Color currentcolor;
static Standard_Boolean highlight = Standard_False;
static Standard_Integer ps_vx, ps_vy;
static Standard_Real ps_kx, ps_ky;
static Standard_Integer ps_px, ps_py;
static ostream* ps_stream;
static Standard_Integer ps_width[MAXCOLOR];
static Standard_Real ps_gray[MAXCOLOR];
enum DrawingMode {DRAW, PICK, POSTSCRIPT};
static DrawingMode CurrentMode = DRAW;
/* local window class */
//=======================================================================
// class View
//=======================================================================
class Draw_View : public Draw_Window {
public :
Draw_View(Standard_Integer i,
Draw_Viewer* v,
Standard_Integer X,
Standard_Integer Y,
Standard_Integer W,
Standard_Integer H);
#if defined(_WIN32) || defined(__WIN32__)
Draw_View(Standard_Integer i,
Draw_Viewer* v,
Standard_Integer X,
Standard_Integer Y,
Standard_Integer W,
Standard_Integer H,
HWND win);
#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
Draw_View(Standard_Integer i,
Draw_Viewer* v,
Standard_Integer X,
Standard_Integer Y,
Standard_Integer W,
Standard_Integer H,
NSWindow* theWindow);
#endif
Draw_View(Standard_Integer i,
Draw_Viewer* v,
const char *w);
void WExpose();
Standard_Boolean Init(const char* typ);
~Draw_View() {Destroy();}
void ResetFrame() { Framex0=Framey0=Framex1=Framey1=0; }
void GetFrame(Standard_Integer& x0,Standard_Integer& y0,
Standard_Integer& x1,Standard_Integer& y1) {
if(Framex0==Framex1) {
viewer->GetFrame(id,x0,y0,x1,y1);
Framex0=x0; Framex1=x1; Framey0=y0; Framey1=y1;
}
else {
x0=Framex0; x1=Framex1;
y0=Framey0; y1=Framey1;
}
}
Standard_Integer id;
Draw_Viewer* viewer;
char type[5];
Standard_Integer FlagPers;
Standard_Integer Flag2d;
Standard_Real FocalDist;
Standard_Real Zoom;
gp_Trsf Matrix;
Standard_Integer dX;
Standard_Integer dY;
Standard_Integer lastX;
Standard_Integer lastY;
Standard_Integer Framex0,Framey0,Framex1,Framey1;
};
//=======================================================================
//function : Draw_View
//purpose :
//=======================================================================
Draw_View::Draw_View(Standard_Integer i, Draw_Viewer* v,
Standard_Integer X,
Standard_Integer Y,
Standard_Integer W,
Standard_Integer H) :
Draw_Window("Win", X, Y, W, H),
id(i),
viewer(v),
FlagPers(0),
Flag2d(0),
FocalDist(0.),
Zoom(0.),
dX(0),dY(0),
lastX(0),lastY(0)
{
Framex0=Framey0=Framex1=Framey1=0;
}
#if defined(_WIN32) || defined(__WIN32__)
//=======================================================================
//function : Draw_View
//purpose :
//=======================================================================
Draw_View::Draw_View(Standard_Integer i, Draw_Viewer* v,
Standard_Integer X,
Standard_Integer Y,
Standard_Integer W,
Standard_Integer H,
HWND theWin) :
Draw_Window("Win", X, Y, W, H, theWin), id(i), viewer(v)
{
Framex0=Framey0=Framex1=Framey1=0;
}
#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
Draw_View::Draw_View(Standard_Integer i, Draw_Viewer* v,
Standard_Integer X,
Standard_Integer Y,
Standard_Integer W,
Standard_Integer H,
NSWindow* theWindow) :
Draw_Window(theWindow, "Win", X, Y, W, H), id(i), viewer(v),
FlagPers(0),
Flag2d(0),
FocalDist(0.),
Zoom(0.),
dX(0),dY(0),
lastX(0),lastY(0),
Framex0(0),Framey0(0),
Framex1(0),Framey1(0)
{
}
#endif
//=======================================================================
//function : Draw_View
//purpose :
//=======================================================================
#if defined(_WIN32) || defined (__WIN32__) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
Draw_View::Draw_View(Standard_Integer /*i*/, Draw_Viewer* /*v*/, const char* /*w*/) : viewer( NULL )
#else
Draw_View::Draw_View(Standard_Integer i, Draw_Viewer* v, const char* w) :
Draw_Window(w), id(i), viewer(v)
#endif
{
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
Standard_Boolean Draw_View::Init (const char* typ)
{
// default fields
Framex0=Framey0=Framex1=Framey1=0;
FocalDist = 500.;
FlagPers = 0;
Flag2d = !strcmp("-2D-",typ);
Zoom = 1;
gp_Trsf T;
gp_Pnt Pvise(0,0,0);
if (!strcmp("+X+Y",typ) || Flag2d)
{
Matrix = T;
}
else if (!strcmp("-Y+X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,0,1)),M_PI/2);
}
else if (!strcmp("-X-Y",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,0,1)),M_PI);
}
else if (!strcmp("+Y-X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,0,1)),-M_PI/2);
}
else if (!strcmp("+Y+X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,0,1)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI);
Matrix.Multiply(T);
}
else if (!strcmp("-X+Y",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI);
}
else if (!strcmp("-Y-X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,0,1)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI);
Matrix.Multiply(T);
}
else if (!strcmp("+X-Y",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI);
}
else if (!strcmp("+X+Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/2);
}
else if (!strcmp("-Z+X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),-M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("-X-Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),-M_PI);
Matrix.Multiply(T);
}
else if (!strcmp("+Z-X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("+Z+X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("-X+Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI);
Matrix.Multiply(T);
}
else if (!strcmp("-Z-X",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),-M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("+X-Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI/2);
}
else if (!strcmp("+Y+Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("-Z+Y",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),-M_PI/2);
}
else if (!strcmp("-Y-Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("+Z-Y",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),-M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI);
Matrix.Multiply(T);
}
else if (!strcmp("+Z+Y",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI/2);
}
else if (!strcmp("-Y+Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("-Z-Y",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI);
Matrix.Multiply(T);
}
else if (!strcmp("+Y-Z",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(0,1,0)),M_PI/2);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),M_PI/2);
Matrix.Multiply(T);
}
else if (!strcmp("AXON",typ))
{
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/4);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,0,1)),-M_PI/4);
Matrix.Multiply(T);
}
else if (!strcmp("PERS",typ))
{
FlagPers =1;
Matrix.SetRotation(gp_Ax1(Pvise,gp_Dir(1,0,0)),-M_PI/4);
T.SetRotation(gp_Ax1(Pvise,gp_Dir(0,0,1)),-M_PI/4);
Matrix.Multiply(T);
}
else {
return Standard_False;
}
strcpy(type,typ);
return Standard_True;
}
//=======================================================================
//function : WExpose
//purpose :
//=======================================================================
void Draw_View::WExpose()
{
Framex0=Framey0=Framex1=Framey1=0;
viewer->RepaintView(id);
}
//=======================================================================
//function : Create
//purpose :
//=======================================================================
Draw_Viewer::Draw_Viewer()
{
if (Draw_Batch) return;
Standard_Integer i;
for ( i = 0; i < MAXVIEW; i++) myViews[i] = NULL;
for (i = 0; i < MAXCOLOR; i++) {
ps_width[i] = 1;
ps_gray[i] = 0;
}
}
//=======================================================================
//function : DefineColor
//purpose :
//=======================================================================
Standard_Boolean Draw_Viewer::DefineColor (const Standard_Integer i, const char* colname)
{
if (Draw_Batch) return 1;
return Draw_Window::DefineColor(i,colname);
}
//=======================================================================
//function : MakeView
//purpose :
//=======================================================================
void Draw_Viewer::MakeView(const Standard_Integer id,
const char* typ,
const Standard_Integer X, const Standard_Integer Y,
const Standard_Integer W, const Standard_Integer H)
{
if (Draw_Batch) return;
if (id < MAXVIEW) {
DeleteView(id);
myViews[id] = new Draw_View(id,this,X , Y, W, H);
// View fields
myViews[id]->dX = W / 2;
myViews[id]->dY = - H / 2;
if (!myViews[id]->Init(typ))
DeleteView(id);
RepaintView(id);
}
}
#ifdef WNT
//=======================================================================
//function : MakeView
//purpose :
//=======================================================================
void Draw_Viewer::MakeView(const Standard_Integer id,
const char* typ,
const Standard_Integer X, const Standard_Integer Y,
const Standard_Integer W, const Standard_Integer H,
HWND win, Standard_Boolean useBuffer)
{
if (Draw_Batch) return;
if (id < MAXVIEW) {
DeleteView(id);
myViews[id] = new Draw_View(id, this, X, Y, W, H, win);
myViews[id]->SetUseBuffer(useBuffer);
// View fields
myViews[id]->dX = W / 2;
myViews[id]->dY = - H / 2;
if (!myViews[id]->Init(typ))
DeleteView(id);
RepaintView(id);
}
}
#endif
//=======================================================================
//function : MakeView
//purpose :
//=======================================================================
void Draw_Viewer::MakeView (const Standard_Integer id,
const char* typ,
const char* window)
{
if (Draw_Batch) return;
if (id < MAXVIEW) {
DeleteView(id);
myViews[id] = new Draw_View(id,this,window);
myViews[id]->dX = myViews[id]->WidthWin() / 2;
myViews[id]->dY = - myViews[id]->HeightWin() / 2;
if (!myViews[id]->Init(typ))
DeleteView(id);
RepaintView(id);
}
}
//=======================================================================
//function : SetTitle
//purpose :
//=======================================================================
void Draw_Viewer::SetTitle (const Standard_Integer id, const char* name)
{
if (Draw_Batch) return;
if(myViews[id]) myViews[id]->SetTitle((char*)name);
}
//=======================================================================
//function : ResetView
//purpose : reset view zoom and axes
//=======================================================================
void Draw_Viewer::ResetView(const Standard_Integer id)
{
if (Draw_Batch) return;
if (myViews[id]) {
myViews[id]->Init(myViews[id]->type);
ConfigView(id);
}
}
//=======================================================================
//function : SetZoom
//purpose :
//=======================================================================
void Draw_Viewer::SetZoom (const Standard_Integer id, const Standard_Real z)
{
if (Draw_Batch) return;
if (myViews[id]) {
Standard_Real zz = z / myViews[id]->Zoom;
myViews[id]->Zoom = z;
Standard_Integer X,Y,W,H;
GetPosSize(id,X,Y,W,H);
Standard_Real w = W;
myViews[id]->dX = (Standard_Integer )( w / 2 - zz * (w/2 - myViews[id]->dX));
Standard_Real h = H;
myViews[id]->dY = (Standard_Integer )( - h / 2 + zz * (h/2 + myViews[id]->dY));
}
}
//=======================================================================
//function : RotateView
//purpose :
//=======================================================================
void Draw_Viewer::RotateView (const Standard_Integer id,
const gp_Dir2d& D,
const Standard_Real A)
{
if (Draw_Batch) return;
if (myViews[id]) {
gp_Trsf T = myViews[id]->Matrix;
T.Invert();
gp_Pnt PP(0,0,0);
gp_Dir DD(D.X(),D.Y(),0);
PP.Transform(T);
DD.Transform(T);
RotateView(id,PP,DD,A);
}
}
//=======================================================================
//function : RotateView
//purpose :
//=======================================================================
void Draw_Viewer::RotateView (const Standard_Integer id,
const gp_Pnt& P,
const gp_Dir& D,
const Standard_Real A)
{
if (Draw_Batch) return;
if (myViews[id]) {
gp_Trsf T;
T.SetRotation(gp_Ax1(P,D),A);
myViews[id]->Matrix.Multiply(T);
}
}
//=======================================================================
//function : SetFocal
//purpose :
//=======================================================================
void Draw_Viewer::SetFocal (const Standard_Integer id, const Standard_Real F)
{
if (Draw_Batch) return;
if (myViews[id])
myViews[id]->FocalDist = F;
}
//=======================================================================
//function : GetType
//purpose :
//=======================================================================
char* Draw_Viewer::GetType (const Standard_Integer id) const
{
if (Draw_Batch) return blank;
if (myViews[id])
return myViews[id]->type;
else
return blank;
}
//=======================================================================
//function : Zoom
//purpose :
//=======================================================================
Standard_Real Draw_Viewer::Zoom (const Standard_Integer id) const
{
if (Draw_Batch) return Standard_False;
if (myViews[id])
return myViews[id]->Zoom;
else
return 0;
}
//=======================================================================
//function : Focal
//purpose :
//=======================================================================
Standard_Real Draw_Viewer::Focal (const Standard_Integer id) const
{
if (Draw_Batch) return 1.;
if (myViews[id])
return myViews[id]->FocalDist;
else
return 0;
}
//=======================================================================
//function : GetTrsf
//purpose :
//=======================================================================
void Draw_Viewer::GetTrsf (const Standard_Integer id,gp_Trsf& T) const
{
if (Draw_Batch) return;
if (myViews[id])
T = myViews[id]->Matrix;
}
//=======================================================================
//function : Is3D
//purpose :
//=======================================================================
Standard_Boolean Draw_Viewer::Is3D (const Standard_Integer id) const
{
if (Draw_Batch) return Standard_False;
if (myViews[id])
return !myViews[id]->Flag2d;
else
return Standard_False;
}
//=======================================================================
//function : SetTrsf
//purpose :
//=======================================================================
void Draw_Viewer::SetTrsf (const Standard_Integer id,gp_Trsf& T)
{
if (Draw_Batch) return;
if (myViews[id])
myViews[id]->Matrix = T;
}
//=======================================================================
//function : GetPosSize
//purpose :
//=======================================================================
void Draw_Viewer::GetPosSize(const Standard_Integer id,
Standard_Integer& X, Standard_Integer& Y,
Standard_Integer& W, Standard_Integer& H)
{
if (Draw_Batch) return;
if (myViews[id] != NULL) {
myViews[id]->GetPosition(X, Y);
W = myViews[id]->WidthWin();
H = myViews[id]->HeightWin();
}
}
//=======================================================================
//function : GetFrame
//purpose :
//=======================================================================
void Draw_Viewer::GetFrame(const Standard_Integer id,
Standard_Integer& xminf, Standard_Integer& yminf,
Standard_Integer& xmaxf, Standard_Integer& ymaxf)
{
if (Draw_Batch) return;
if (myViews[id]) {
Standard_Integer X,Y,H,W;
GetPosSize(id,X,Y,W,H);
xminf = - myViews[id]->dX;
xmaxf = W - myViews[id]->dX;
yminf = - myViews[id]->dY - H;
ymaxf = - myViews[id]->dY;
}
}
//=======================================================================
//function : FitView
//purpose :
//=======================================================================
void Draw_Viewer::FitView(const Standard_Integer id, const Standard_Integer frame)
{
if (Draw_Batch) return;
if (myViews[id]) {
// is this the only view in its category
Standard_Integer is2d = myViews[id]->Flag2d;
Standard_Integer i,nbviews = 0;
for (i = 1; i < MAXVIEW; i++) {
if (myViews[i]) {
if (myViews[i]->Flag2d == is2d) nbviews++;
}
}
Standard_Boolean only = (nbviews == 1);
Standard_Integer X,Y,H,W;
GetPosSize(id,X,Y,W,H);
// compute the min max
Standard_Integer n = myDrawables.Length();
if (n == 0) return;
// Draw_Display DF;
curview = myViews[id];
Standard_Real umin,umax,vmin,vmax;
Standard_Real u1,u2,v1,v2;
umin = vmin = DRAWINFINITE;
umax = vmax = -DRAWINFINITE;
for (i = 1; i <= n; i++) {
Standard_Boolean d3d = myDrawables(i)->Is3D();
if ((d3d && !is2d) || (!d3d && is2d)) {
// if this is not the only view recompute...
if (!only)
DrawOnView(id,myDrawables(i));
myDrawables(i)->Bounds(u1,u2,v1,v2);
if (u1 < umin) umin = u1;
if (u2 > umax) umax = u2;
if (v1 < vmin) vmin = v1;
if (v2 > vmax) vmax = v2;
}
}
Standard_Real z;
umin = umin / curview->Zoom;
vmin = vmin / curview->Zoom;
umax = umax / curview->Zoom;
vmax = vmax / curview->Zoom;
if ((umax - umin) < 1.e-6) {
if ((vmax - vmin) < 1.e-6)
return;
else
z = ((Standard_Real)(H - 2*frame)) / (vmax - vmin);
}
else {
z = ((Standard_Real)(W - 2*frame)) /((Standard_Real) (umax - umin));
if ((vmax - vmin) > 1.e-6) {
Standard_Real z2 = ((Standard_Real)(H - 2*frame)) /(vmax - vmin);
if (z2 < z) z = z2;
}
}
curview->Zoom = z;
curview->dX = (Standard_Integer )( W / 2 - ((umin+umax) / 2) * z);
curview->dY = (Standard_Integer )( - H / 2 - ((vmin+vmax) / 2) * z);
}
}
//=======================================================================
//function : PanView
//purpose :
//=======================================================================
void Draw_Viewer::PanView(const Standard_Integer id,
const Standard_Integer DX, const Standard_Integer DY)
{
if (Draw_Batch) return;
if (myViews[id]) {
myViews[id]->dX += DX;
myViews[id]->dY += DY;
}
}
//=======================================================================
//function : SetPan
//purpose :
//=======================================================================
void Draw_Viewer::SetPan(const Standard_Integer id,
const Standard_Integer DX, const Standard_Integer DY)
{
if (Draw_Batch) return;
if (myViews[id]) {
myViews[id]->dX = DX;
myViews[id]->dY = DY;
}
}
//=======================================================================
//function : GetPan
//purpose :
//=======================================================================
void Draw_Viewer::GetPan(const Standard_Integer id,
Standard_Integer& DX, Standard_Integer& DY)
{
if (Draw_Batch) return;
if (myViews[id]) {
DX = myViews[id]->dX;
DY = myViews[id]->dY;
}
}
//=======================================================================
//function : HasView
//purpose :
//=======================================================================
Standard_Boolean Draw_Viewer::HasView(const Standard_Integer id) const
{
if (Draw_Batch) return Standard_False;
if ((id < 0) || id >= MAXVIEW) return Standard_False;
return myViews[id] != NULL;
}
//=======================================================================
//function : DisplayView
//purpose :
//=======================================================================
void Draw_Viewer::DisplayView (const Standard_Integer id) const
{
if (Draw_Batch) return;
if (myViews[id]) myViews[id]->DisplayWindow();
}
//=======================================================================
//function : HideView
//purpose :
//=======================================================================
void Draw_Viewer::HideView (const Standard_Integer id) const
{
if (Draw_Batch) return;
if (myViews[id]) {
//
}
}
//=======================================================================
//function : ClearView
//purpose :
//=======================================================================
void Draw_Viewer::ClearView(const Standard_Integer id) const
{
if (Draw_Batch) return;
if (myViews[id]) myViews[id]->Clear();
}
//=======================================================================
//function : RemoveView
//purpose :
//=======================================================================
void Draw_Viewer::RemoveView(const Standard_Integer id)
{
if (Draw_Batch) return;
if (myViews[id]) {
delete myViews[id];
myViews[id] = NULL;
}
}
//=======================================================================
//function : RepaintView
//purpose :
//=======================================================================
void Draw_Viewer::RepaintView (const Standard_Integer id) const
{
if (Draw_Batch) return;
if (myViews[id]) {
ClearView(id);
Standard_Integer n = myDrawables.Length();
for (Standard_Integer i = 1; i <= n; i++)
DrawOnView(id,myDrawables(i));
}
}
#ifdef WNT
//=======================================================================
//function : ResizeView
//purpose : WNT re-drawing optimization
//=======================================================================
void Draw_Viewer::ResizeView (const Standard_Integer id) const
{
if (Draw_Batch) return;
if (myViews[id] && myViews[id]->GetUseBuffer()) {
myViews[id]->InitBuffer();
RepaintView(id);
}
}
//=======================================================================
//function : UpdateView
//purpose : WNT re-drawing optimization
//=======================================================================
void Draw_Viewer::UpdateView (const Standard_Integer id, const Standard_Boolean forced) const
{
if (Draw_Batch) return;
if (myViews[id]) {
if (!myViews[id]->GetUseBuffer() || forced) {
RepaintView(id);
}
// Fast redrawing on WNT
if (myViews[id]->GetUseBuffer()) myViews[id]->Redraw();
}
}
#endif
//=======================================================================
//function : ConfigView
//purpose :
//=======================================================================
void Draw_Viewer::ConfigView (const Standard_Integer id) const
{
if (Draw_Batch) return;
if (myViews[id]) {
myViews[id]->dX = myViews[id]->WidthWin() / 2;
myViews[id]->dY = - myViews[id]->HeightWin() / 2;
}
}
//=======================================================================
//function : PostScriptView
//purpose :
//=======================================================================
void Draw_Viewer::PostScriptView (const Standard_Integer id,
const Standard_Integer VXmin,
const Standard_Integer VYmin,
const Standard_Integer VXmax,
const Standard_Integer VYmax,
const Standard_Integer PXmin,
const Standard_Integer PYmin,
const Standard_Integer PXmax,
const Standard_Integer PYmax,
ostream& sortie) const
{
if (Draw_Batch) return;
if (myViews[id]) {
ps_vx = VXmin;
ps_vy = VYmin;
ps_px = PXmin;
ps_py = PYmin;
ps_kx = ((Standard_Real) (PXmax - PXmin)) / ((Standard_Real) (VXmax - VXmin));
ps_ky = ((Standard_Real) (PYmax - PYmin)) / ((Standard_Real) (VYmax - VYmin));
ps_stream = &sortie;
Standard_Integer n = myDrawables.Length();
if (n == 0) return;
CurrentMode = POSTSCRIPT;
Draw_Display DF = MakeDisplay(id);
Standard_Boolean view2d = myViews[id]->Flag2d;
for (Standard_Integer i = 1; i <= n; i++)
if (myDrawables(i)->Is3D()) {
if (!view2d) myDrawables(i)->DrawOn(DF);
}
else {
if (view2d) myDrawables(i)->DrawOn(DF);
}
sortie << "stroke\n";
CurrentMode = DRAW;
}
}
//=======================================================================
//function : PostColor
//purpose :
//=======================================================================
void Draw_Viewer::PostColor(const Standard_Integer icol,
const Standard_Integer width,
const Standard_Real gray)
{
if (Draw_Batch) return;
if ((icol < 0) || (icol >= MAXCOLOR)) return;
ps_width[icol] = width;
ps_gray[icol] = gray;
}
//=======================================================================
//function : SaveView
//purpose :
//=======================================================================
Standard_Boolean Draw_Viewer::SaveView(const Standard_Integer id,
const char* filename)
{
if (Draw_Batch) return Standard_False;;
Flush();
if (myViews[id]) {
return myViews[id]->Save(filename);
}
else
{
std::cerr << "View " << id << " doesn't exists!\n";
return Standard_False;
}
}
//=======================================================================
//function : RepaintAll
//purpose :
//=======================================================================
void Draw_Viewer::RepaintAll () const
{
if (Draw_Batch) return;
for (Standard_Integer id = 0; id < MAXVIEW; id++)
RepaintView(id);
}
//=======================================================================
//function : Repaint2D
//purpose :
//=======================================================================
void Draw_Viewer::Repaint2D () const
{
if (Draw_Batch) return;
for (Standard_Integer id = 0; id < MAXVIEW; id++)
if (myViews[id]) {
if (myViews[id]->Flag2d) RepaintView(id);
}
}
//=======================================================================
//function : Repaint3D
//purpose :
//=======================================================================
void Draw_Viewer::Repaint3D () const
{
if (Draw_Batch) return;
for (Standard_Integer id = 0; id < MAXVIEW; id++)
if (myViews[id]) {
if (!myViews[id]->Flag2d) RepaintView(id);
}
}
//=======================================================================
//function : DeleteView
//purpose :
//=======================================================================
void Draw_Viewer::DeleteView(const Standard_Integer id)
{
if (Draw_Batch) return;
if (myViews[id] != NULL) {
delete myViews[id];
myViews[id] = NULL;
}
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void Draw_Viewer::Clear()
{
if (Draw_Batch) return;
for (Standard_Integer i = 1; i <= myDrawables.Length(); i++)
myDrawables(i)->Visible(Standard_False);
myDrawables.Clear();
for (Standard_Integer id = 0; id < MAXVIEW; id++)
ClearView(id);
}
//=======================================================================
//function : Clear2D
//purpose :
//=======================================================================
void Draw_Viewer::Clear2D()
{
if (Draw_Batch) return;
Standard_Integer i = 1;
while (i <= myDrawables.Length()) {
if (myDrawables(i)->Is3D())
i++;
else {
myDrawables(i)->Visible(Standard_False);
myDrawables.Remove(i);
}
}
for (Standard_Integer id = 0; id < MAXVIEW; id++) {
if (myViews[id]) {
if (myViews[id]->Flag2d)
ClearView(id);
}
}
}
//=======================================================================
//function : Clear3D
//purpose :
//=======================================================================
void Draw_Viewer::Clear3D()
{
if (Draw_Batch) return;
Standard_Integer i = 1;
while (i <= myDrawables.Length()) {
if (myDrawables(i)->Is3D()) {
myDrawables(i)->Visible(Standard_False);
myDrawables.Remove(i);
}
else
i++;
}
for (Standard_Integer id = 0; id < MAXVIEW; id++) {
if (myViews[id]) {
if (!myViews[id]->Flag2d)
ClearView(id);
}
}
}
//=======================================================================
//function : Flush
//purpose :
//=======================================================================
void Draw_Viewer::Flush()
{
if (Draw_Batch) return;
Draw_Window::Flush();
}
//=======================================================================
//function : DrawOnView
//purpose :
//=======================================================================
void Draw_Viewer::DrawOnView(const Standard_Integer id,
const Handle(Draw_Drawable3D)& D) const
{
if (Draw_Batch) return;
if (myViews[id]) {
Draw_Display d = MakeDisplay(id);
xmin = ymin = DRAWINFINITE;
xmax = ymax = -DRAWINFINITE;
Standard_Boolean view2d = myViews[id]->Flag2d;
myViews[id]->ResetFrame();
if ((D->Is3D() && !view2d) ||
(!D->Is3D() && view2d)) {
D->DrawOn(d);
if (CurrentMode == DRAW)
D->SetBounds(xmin,xmax,ymin,ymax);
d.Flush();
}
}
}
//=======================================================================
//function : HighlightOnView
//purpose :
//=======================================================================
void Draw_Viewer::HighlightOnView (const Standard_Integer id,
const Handle(Draw_Drawable3D)& D,
const Draw_ColorKind C) const
{
if (Draw_Batch) return;
highlight = Standard_True;
highlightcol = C;
DrawOnView(id,D);
highlight = Standard_False;
}
//=======================================================================
//function : AddDrawable
//purpose :
//=======================================================================
void Draw_Viewer::AddDrawable (const Handle(Draw_Drawable3D)& D)
{
if (Draw_Batch) return;
if (!D.IsNull() && !D->Visible()) {
myDrawables.Append(D);
D->Visible(Standard_True);
}
}
//=======================================================================
//function : RemoveDrawable
//purpose :
//=======================================================================
void Draw_Viewer::RemoveDrawable (const Handle(Draw_Drawable3D)& D)
{
if (Draw_Batch) return;
if (!D.IsNull() && D->Visible()) {
Standard_Integer index;
for (index = 1; index <= myDrawables.Length(); index++) {
if (myDrawables(index) == D) {
D->Visible(Standard_False);
myDrawables.Remove(index);
return;
}
}
}
}
//=======================================================================
//function : MakeDisplay
//purpose : return a display on the view
//=======================================================================
Draw_Display Draw_Viewer::MakeDisplay (const Standard_Integer id) const
{
if (Draw_Batch) {Draw_Display dis;return dis;}
curviewId = id;
curview = myViews[id];
int GXcopy = 0x3;
nbseg = 0;
Draw_Color initcol(Draw_blanc);
// to force setting the color
currentcolor = Draw_Color(Draw_rouge);
Draw_Display dis;
dis.SetColor(initcol);
dis.SetMode(GXcopy);
return dis;
}
//=======================================================================
//function : Select
//purpose :
//=======================================================================
void Draw_Viewer::Select (Standard_Integer& id, Standard_Integer& X, Standard_Integer& Y,
Standard_Integer& Button, Standard_Boolean wait)
{
if (Draw_Batch) return;
Flush();
#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
if (!wait) {
if (id >=0 && id < MAXVIEW) {
if (myViews[id]) myViews[id]->Wait(wait);
}
}
else {
for(int i=0 ; i<MAXVIEW ; i++)
if (myViews[i]) myViews[i]->Wait(wait);
}
Standard_Boolean again = Standard_True;
while (again) {
Event ev;
ev.type = 0;
GetNextEvent(ev);
switch (ev.type) {
case ButtonPress :
Standard_Integer iv;
for (iv = 0; iv < MAXVIEW; iv++) {
if (myViews[iv]) {
if (myViews[iv]->win == ev.window)
break;
}
}
if (wait || id == iv) {
if (iv < MAXVIEW) {
id = iv;
X = ev.x;
Y = ev.y;
Button = ev.button;
}
else {
id = -1;
}
again = Standard_False;
}
break;
case MotionNotify :
if (wait) break;
X = ev.x;
Y = ev.y;
Button = 0;
again = Standard_False;
break;
}
}
if (id != -1) {
X = X - myViews[id]->dX;
Y = -Y - myViews[id]->dY;
}
if (!wait) myViews[id]->Wait(!wait);
#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
Standard_Integer aWindowNumber;
id = MAXVIEW;
while (id >= MAXVIEW)
{
GetNextEvent(wait, aWindowNumber, X, Y, Button);
if (Y < 0)
{
continue; // mouse clicked on window title
}
for (Standard_Integer anIter = 0; anIter < MAXVIEW; anIter++)
{
if (myViews[anIter] && myViews[anIter]->IsEqualWindows (aWindowNumber))
{
id = anIter;
}
}
}
X = X - myViews[id]->dX;
Y = -Y - myViews[id]->dY;
#else
HANDLE hWnd;
id = MAXVIEW; //:abv 29.05.02: cycle for working in console mode
while ( id >= MAXVIEW ) {
if (wait)
Draw_Window::SelectWait(hWnd, X, Y, Button);
else
Draw_Window::SelectNoWait(hWnd, X, Y, Button);
// Recherche du numero de la vue grace au HANDLE
for(int i=0 ; i<MAXVIEW ; i++)
if (myViews[i] && myViews[i]->win == hWnd ) id = i;
}
X = X - myViews[id]->dX;
Y = -Y - myViews[id]->dY;
#endif
}
//=======================================================================
//function : Pick
//purpose :
//=======================================================================
Standard_Integer Draw_Viewer::Pick(const Standard_Integer id,
const Standard_Integer X, const Standard_Integer Y, const Standard_Integer Prec,
Handle(Draw_Drawable3D)& D,
const Standard_Integer first) const
{
if (Draw_Batch) return 0;
if (myViews[id] == NULL)
return 0;
// is this the only view in its category
Standard_Integer is2d = myViews[id]->Flag2d;
Standard_Integer i,nbviews = 0;
for (i = 0; i < MAXVIEW; i++) {
if (myViews[i]) {
if (myViews[i]->Flag2d == is2d) nbviews++;
}
}
Standard_Boolean only = (nbviews == 1);
CurrentMode = PICK;
xpick = X;
ypick = Y;
precpick = Prec;
found = Standard_False;
Standard_Real x1,x2,y1,y2;
for (i = first+1; i <= myDrawables.Length(); i++) {
Standard_Boolean reject = Standard_False;
// rejection if only view
if (only) {
myDrawables(i)->Bounds(x1,x2,y1,y2);
if ((xpick+Prec < x1) || (xpick-Prec > x2) ||
(ypick+Prec < y1) || (ypick-Prec > y2))
reject = Standard_True;
}
if (!reject) {
DrawOnView(id,myDrawables(i));
if (found)
break;
}
}
CurrentMode = DRAW;
found = Standard_False;
if (i <= myDrawables.Length())
D = myDrawables(i);
else
i = 0;
return i;
}
//=======================================================================
//function : LastPick
//purpose :
//=======================================================================
void Draw_Viewer::LastPick(gp_Pnt& P1, gp_Pnt& P2, Standard_Real& Param)
{
if (Draw_Batch) return;
P1 = lastPickP1;
P2 = lastPickP2;
Param = lastPickParam;
}
//=======================================================================
//function : ~Draw_Viewer
//purpose :
//=======================================================================
Draw_Viewer::~Draw_Viewer()
{
if (Draw_Batch) return;
for (Standard_Integer id = 0; id < MAXVIEW; id++)
DeleteView(id);
}
//=======================================================================
//function : operator<<
//purpose :
//=======================================================================
Draw_Viewer& Draw_Viewer::operator<<(const Handle(Draw_Drawable3D)& d3d)
{
if (Draw_Batch) return *this;
if (!d3d.IsNull()) {
AddDrawable(d3d);
for (Standard_Integer id = 0; id < MAXVIEW; id++)
DrawOnView(id,d3d);
}
return *this;
}
//=======================================================================
//function : GetDrawables
//purpose :
//=======================================================================
const Draw_SequenceOfDrawable3D& Draw_Viewer::GetDrawables()
{
return myDrawables;
}
// *******************************************************************
// DISPLAY methods
// *******************************************************************
void Draw_Flush()
{
if (Draw_Batch) return;
if (highlight) curview->SetColor(highlightcol.ID());
curview->DrawSegments(segm,nbseg);
nbseg = 0;
}
//=======================================================================
//function : SetColor
//purpose :
//=======================================================================
void Draw_Display::SetColor (const Draw_Color& col) const
{
if (Draw_Batch) return;
if (col.ID() == currentcolor.ID()) return;
currentcolor = col;
switch (CurrentMode) {
case DRAW :
Draw_Flush();
curview->SetColor(col.ID());
break;
case POSTSCRIPT :
(*ps_stream) << "stroke\nnewpath\n";
(*ps_stream) << ps_width[col.ID()]<<" setlinewidth\n";
(*ps_stream) << ps_gray[col.ID()]<<" setgray\n";
case PICK :
break;
}
}
//=======================================================================
//function : SetMode
//purpose :
//=======================================================================
void Draw_Display::SetMode (const Standard_Integer M) const
{
if (Draw_Batch) return;
switch (CurrentMode) {
case DRAW :
Draw_Flush();
curview->SetMode(M);
break;
case PICK :
case POSTSCRIPT :
break;
}
}
//=======================================================================
//function : Zoom
//purpose :
//=======================================================================
Standard_Real Draw_Display::Zoom() const
{
if (Draw_Batch) return 1.;
return curview->Zoom;
}
//=======================================================================
//function : Flush
//purpose :
//=======================================================================
void Draw_Display::Flush () const
{
if (Draw_Batch) return;
Draw_Flush();
}
//=======================================================================
//function : DrawString
//purpose :
//=======================================================================
void Draw_Display::DrawString(const gp_Pnt2d& ppt,
const Standard_CString S,
const Standard_Real moveX,
const Standard_Real moveY)
{
if (Draw_Batch) return;
if (ppt.X() > 1.e09 || ppt.X() < -1.e09 ) return;
if (ppt.Y() > 1.e09 || ppt.Y() < -1.e09 ) return;
gp_Pnt2d pt(ppt.X()*curview->Zoom,ppt.Y()*curview->Zoom);
if (pt.X() > 1.e09 || pt.X() < -1.e09 ) return;
if (pt.Y() > 1.e09 || pt.Y() < -1.e09 ) return;
switch (CurrentMode) {
case DRAW :
{
int X = (int) ( pt.X() + moveX + curview->dX);
int Y = (int) (-pt.Y() + moveY - curview->dY);
curview->DrawString(X,Y,(char *)S);
if (Draw_Bounds) {
if (pt.X() + moveX > xmax) xmax = pt.X();
if (pt.X() + moveX < xmin) xmin = pt.X();
if (-pt.Y() - moveY > ymax) ymax = -pt.Y();
if (-pt.Y() - moveY < ymin) ymin = -pt.Y();
}
}
break;
case POSTSCRIPT :
{
Standard_Integer x = (Standard_Integer )( (pt.X() + moveX - ps_vx) * ps_kx + ps_px);
Standard_Integer y = (Standard_Integer )( (pt.Y() + moveY - ps_vy) * ps_ky + ps_py);
(*ps_stream) <<"stroke\n";
(*ps_stream) << x << " " << y << " m\n";
(*ps_stream) <<"("<<S<<") show\nnewpath\n";
}
break;
case PICK :
break;
}
}
//=======================================================================
//function : DrawString
//purpose :
//=======================================================================
void Draw_Display::DrawString(const gp_Pnt2d& ppt,
const Standard_CString S)
{
if (Draw_Batch) return;
DrawString(ppt,S,0.0,0.0);
}
//=======================================================================
//function : DrawString
//purpose :
//=======================================================================
void Draw_Display::DrawString(const gp_Pnt& pt,
const Standard_CString S,
const Standard_Real moveX,
const Standard_Real moveY)
{
if (Draw_Batch) return;
DrawString(Project(pt),S,moveX,moveY);
}
//=======================================================================
//function : DrawString
//purpose :
//=======================================================================
void Draw_Display::DrawString(const gp_Pnt& pt,
const Standard_CString S)
{
if (Draw_Batch) return;
DrawString(Project(pt),S,0.0,0.0);
}
// *******************************************************************
// Drawing data static variables
// *******************************************************************
static gp_Pnt2d PtCur; // current 2D point
static gp_Pnt PtPers; // current 3D point for Pers
//=======================================================================
//function : Project
//purpose :
//=======================================================================
void Draw_Display::Project(const gp_Pnt& p, gp_Pnt2d& p2d) const
{
if (Draw_Batch) return;
gp_Pnt pt = p;
pt.Transform(curview->Matrix);
Standard_Real xp,yp,zp;
pt.Coord(xp,yp,zp);
if (curview->FlagPers) {
xp = xp*curview->FocalDist/(curview->FocalDist-zp);
yp = yp*curview->FocalDist/(curview->FocalDist-zp);
}
p2d.SetCoord(xp,yp);
}
//=======================================================================
//function : Draw_Display
//purpose :
//=======================================================================
Draw_Display::Draw_Display ()
{
if (Draw_Batch) return;
if (curview) {
PtPers.SetCoord(0,0,0);
PtPers.Transform(curview->Matrix);
PtCur.SetCoord(PtPers.X()*curview->Zoom,PtPers.Y()*curview->Zoom);
}
}
//=======================================================================
//function : MoveTo 2D
//purpose :
//=======================================================================
void Draw_Display::MoveTo (const gp_Pnt2d& pp)
{
if (Draw_Batch) return;
gp_Pnt2d pt(pp.X() * curview->Zoom, pp.Y() * curview->Zoom);
switch (CurrentMode) {
case DRAW :
PtCur = pt;
if (Draw_Bounds) {
if (pt.X() > xmax) xmax = pt.X();
if (pt.X() < xmin) xmin = pt.X();
if (pt.Y() > ymax) ymax = pt.Y();
if (pt.Y() < ymin) ymin = pt.Y();
}
break;
case PICK :
PtCur = pt;
break;
case POSTSCRIPT :
{
Standard_Integer x = (Standard_Integer )( (pt.X() - ps_vx) * ps_kx + ps_px);
Standard_Integer y = (Standard_Integer )( (pt.Y() - ps_vy) * ps_ky + ps_py);
(*ps_stream) <<"stroke\nnewpath\n"<< x << " " << y << " m\n";
}
break;
}
}
//=======================================================================
//function : DrawTo 2D
//purpose :
//=======================================================================
inline Standard_Integer CalculRegion(const Standard_Real x,
const Standard_Real y,
const Standard_Real x1,
const Standard_Real y1,
const Standard_Real x2,
const Standard_Real y2) {
Standard_Integer r;
if(x<x1) { r=1; } else { if(x>x2) { r=2; } else { r=0; } }
if(y<y1) { r|=4; } else { if(y>y2) { r|=8; } }
return(r);
}
Standard_Boolean Trim(gp_Pnt2d& P1,gp_Pnt2d& P2,
Standard_Real x0,
Standard_Real y0,
Standard_Real x1,
Standard_Real y1) {
Standard_Real xa=P1.X(),ya=P1.Y(),xb=P2.X(),yb=P2.Y();
Standard_Integer regiona=0,regionb=0;
regiona = CalculRegion(xa,ya,x0,y0,x1,y1);
regionb = CalculRegion(xb,yb,x0,y0,x1,y1);
if((regiona & regionb)==0) {
Standard_Real dx=xb-xa;
Standard_Real dy=yb-ya;
Standard_Real dab=sqrt(dx*dx+dy*dy);
if(dab<1e-10) return(Standard_False);
dx/=dab;
dy/=dab;
Standard_Real xm,ym,mfenx,mfeny;
mfenx=xm=0.5*(x0+x1);
mfeny=ym=0.5*(y0+y1);
x1-=x0; y1-=y0;
Standard_Real d=sqrt(x1*x1+y1*y1) * 2;
Standard_Real p=(xm-xa)*dx+(ym-ya)*dy;
xm=xa+p*dx;
ym=ya+p*dy;
gp_Pnt2d Pm(xm,ym);
gp_Pnt2d MFen(mfenx,mfeny);
if(MFen.SquareDistance(Pm) > d*d) return(Standard_False);
Standard_Real PmDistP1 = Pm.Distance(P1);
Standard_Real PmDistP2 = Pm.Distance(P2);
Standard_Real amab = (xm-xa)*(xb-xa)+(ym-ya)*(yb-ya);
if(amab > 0) { //-- M est compris entre A et B
if(PmDistP1 > d) {
P1.SetCoord(xm-d*dx,ym-d*dy);
}
if(PmDistP2 >d) {
P2.SetCoord(xm+d*dx,ym+d*dy);
}
}
else if(PmDistP1 < PmDistP2) { //-- On a M P1 P2
if(PmDistP2 > d) {
P2.SetCoord(xm+d*dx,ym+d*dy);
}
}
else { //-- On a P1 P2 M
if(PmDistP1 > d) {
P1.SetCoord(xm-d*dx,ym-d*dy);
}
}
return(Standard_True);
}
else return(Standard_False);
}
void Draw_Display::DrawTo (const gp_Pnt2d& pp2)
{
if (Draw_Batch) return;
if (pp2.X() > 1.e09 || pp2.X() < -1.e09 ) return;
if (pp2.Y() > 1.e09 || pp2.Y() < -1.e09 ) return;
gp_Pnt2d p2(pp2.X() * curview->Zoom, pp2.Y() * curview->Zoom);
if (p2.X() > 1.e09 || p2.X() < -1.e09 ) return;
if (p2.Y() > 1.e09 || p2.Y() < -1.e09 ) return;
gp_Pnt2d p1 = PtCur;
if (p1.X() > 1.e09 || p1.X() < -1.e09 ) return;
if (p1.Y() > 1.e09 || p1.Y() < -1.e09 ) return;
PtCur = p2;
switch (CurrentMode) {
case DRAW : {
#if 1
Standard_Integer x0,y0,x1,y1;
curview->GetFrame(x0,y0,x1,y1);
//Standard_Integer qx0,qy0,qx1,qy1;
//curview->viewer->GetFrame(curview->id,qx0,qy0,qx1,qy1);
//if(qx0!=x0 || qx1!=x1 || qy0!=y0 || qy1!=y1) {
// x0=qx0; x1=qx1; y0=qy0; y1=qy1;
//}
gp_Pnt2d PI1(p1);
gp_Pnt2d PI2(p2);
if(Trim(PI1,PI2,x0,y0,x1,y1)) {
segm[nbseg].Init((Standard_Integer )( PI1.X() + curview->dX),
(Standard_Integer )(-PI1.Y() - curview->dY),
(Standard_Integer )( PI2.X() + curview->dX),
(Standard_Integer )(-PI2.Y() - curview->dY));
nbseg++;
}
#else
segm[nbseg].Init(( p1.X() + curview->dX),
(-p1.Y() - curview->dY),
( p2.X() + curview->dX),
(-p2.Y() - curview->dY));
nbseg++;
#endif
if (nbseg == MAXSEGMENT) {
Draw_Flush();
}
if (Draw_Bounds) {
if (p2.X() > xmax) xmax = p2.X();
if (p2.X() < xmin) xmin = p2.X();
if (p2.Y() > ymax) ymax = p2.Y();
if (p2.Y() < ymin) ymin = p2.Y();
}
}
break;
case PICK :
if (!found) {
Standard_Integer x1 = (int) p1.X() ;
Standard_Integer y1 = (int) p1.Y() ;
Standard_Integer x2 = (int) p2.X() ;
Standard_Integer y2 = (int) p2.Y() ;
if ((x1 >= xpick + precpick) && (x2 >= xpick + precpick)) break;
if ((x1 <= xpick - precpick) && (x2 <= xpick - precpick)) break;
if ((y1 >= ypick + precpick) && (y2 >= ypick + precpick)) break;
if ((y1 <= ypick - precpick) && (y2 <= ypick - precpick)) break;
Standard_Boolean inside = Standard_True;
if ((x1 > xpick + precpick) || (x2 > xpick + precpick)) {
Standard_Real y = (Standard_Real) y1 +
(Standard_Real) (y2-y1) * (Standard_Real) (xpick+precpick-x1) /
(Standard_Real) (x2 - x1);
if ( (y < ypick+precpick) && (y > ypick - precpick)) {
found = Standard_True;
lastPickParam = (Standard_Real) (xpick - x1) /
(Standard_Real) (x2 - x1);
break;
}
else
inside = Standard_False;
}
if ((x1 < xpick - precpick) || (x2 < xpick - precpick)) {
Standard_Real y = (Standard_Real) y1 +
(Standard_Real) (y2-y1) * (Standard_Real) (xpick-precpick-x1) /
(Standard_Real) (x2 - x1);
if ( (y < ypick+precpick) && (y > ypick - precpick)) {
found = Standard_True;
lastPickParam = (Standard_Real) (xpick - x1) /
(Standard_Real) (x2 - x1);
break;
}
else
inside = Standard_False;
}
if ((y1 > ypick + precpick) || (y2 > ypick + precpick)) {
Standard_Real x = (Standard_Real) x1 +
(Standard_Real) (x2-x1) * (Standard_Real) (ypick+precpick-y1) /
(Standard_Real) (y2 - y1);
if ( (x < xpick+precpick) && (x > xpick - precpick)) {
found = Standard_True;
lastPickParam = (Standard_Real) (ypick - y1) /
(Standard_Real) (y2 - y1);
break;
}
else
inside = Standard_False;
}
if ((y1 < ypick - precpick) || (y2 < ypick - precpick)) {
Standard_Real x = (Standard_Real) x1 +
(Standard_Real) (x2-x1) * (Standard_Real) (ypick-precpick-y1) /
(Standard_Real) (y2 - y1);
if ( (x < xpick+precpick) && (x > xpick - precpick)) {
found = Standard_True;
lastPickParam = (Standard_Real) (ypick - y1) /
(Standard_Real) (y2 - y1);
break;
}
else
inside = Standard_False;
}
found = found || inside;
if (found) {
if (Abs(x2-x1) > Abs(y2-y1)) {
if (Abs(x2-x1) < 1e-5) lastPickParam = 0;
else
lastPickParam = (Standard_Real)(xpick - x1) /
(Standard_Real)(x2 - x1);
}
else {
if (Abs(y2-y1) < 1e-5) lastPickParam = 0;
else
lastPickParam = (Standard_Real)(ypick - y1) /
(Standard_Real)(y2 - y1);
}
}
}
break;
case POSTSCRIPT :
{
Standard_Integer x = (Standard_Integer )( (p2.X() - ps_vx) * ps_kx + ps_px);
Standard_Integer y = (Standard_Integer )( (p2.Y() - ps_vy) * ps_ky + ps_py);
(*ps_stream) << x << " " << y << " l\n";
}
break;
}
}
//=======================================================================
//function : MoveTo
//purpose :
//=======================================================================
void Draw_Display::MoveTo (const gp_Pnt& pt)
{
if (Draw_Batch) return;
if (CurrentMode == PICK) {
if (!found) lastPickP1 = pt;
else return;
}
PtPers = pt;
PtPers.Transform(curview->Matrix);
Standard_Real xp = PtPers.X();
Standard_Real yp = PtPers.Y();
if (curview->FlagPers) {
Standard_Real ZPers = PtPers.Z();
if (ZPers < curview->FocalDist*precpers) {
xp=xp*curview->FocalDist/(curview->FocalDist-ZPers);
yp=yp*curview->FocalDist/(curview->FocalDist-ZPers);
}
}
MoveTo(gp_Pnt2d(xp,yp));
}
//=======================================================================
//function : DrawTo
//purpose :
//=======================================================================
void Draw_Display::DrawTo (const gp_Pnt& pt)
{
if (Draw_Batch) return;
if ((CurrentMode == PICK) && found) return;
gp_Pnt pt2 = pt.Transformed(curview->Matrix);
Standard_Real xp2 = pt2.X();
Standard_Real yp2 = pt2.Y();
if (curview->FlagPers) {
Standard_Real xp1 = PtPers.X();
Standard_Real yp1 = PtPers.Y();
Standard_Real zp1 = PtPers.Z();
Standard_Real zp2 = pt2.Z();
PtPers = pt2;
if ((zp1 >= curview->FocalDist*precpers) &&
(zp2 >= curview->FocalDist*precpers) ) {
return; // segment is not visible in perspective (behind the eye)
}
else if (zp1 >= curview->FocalDist*precpers) {
xp1=xp1+(xp2-xp1)*(curview->FocalDist*precpers-zp1)/(zp2-zp1);
yp1=yp1+(yp2-yp1)*(curview->FocalDist*precpers-zp1)/(zp2-zp1);
zp1=curview->FocalDist*precpers;
xp1=xp1*curview->FocalDist/(curview->FocalDist-zp1);
yp1=yp1*curview->FocalDist/(curview->FocalDist-zp1);
MoveTo(gp_Pnt2d(xp1*curview->Zoom,yp1*curview->Zoom));
}
else if (zp2 >= curview->FocalDist*precpers) {
xp2=xp2+(xp1-xp2)*(curview->FocalDist*precpers-zp2)/(zp1-zp2);
yp2=yp2+(yp1-yp2)*(curview->FocalDist*precpers-zp2)/(zp1-zp2);
zp2=curview->FocalDist*precpers;
}
xp2=xp2*curview->FocalDist/(curview->FocalDist-zp2);
yp2=yp2*curview->FocalDist/(curview->FocalDist-zp2);
}
DrawTo(gp_Pnt2d(xp2,yp2));
if (CurrentMode == PICK) {
if (!found) lastPickP1 = pt;
else lastPickP2 = pt;
}
}
//=======================================================================
//function : Draw
//purpose :
//=======================================================================
void Draw_Display::Draw (const gp_Pnt& p1, const gp_Pnt& p2)
{
if (Draw_Batch) return;
MoveTo(p1);
DrawTo(p2);
}
//=======================================================================
//function : Draw
//purpose :
//=======================================================================
void Draw_Display::Draw(const gp_Pnt2d& p1, const gp_Pnt2d& p2)
{
if (Draw_Batch) return;
MoveTo(p1);
DrawTo(p2);
}
//=======================================================================
//function : ViewId
//purpose :
//=======================================================================
Standard_Integer Draw_Display::ViewId() const
{
if (Draw_Batch) return 0;
return curviewId;
}
//=======================================================================
//function : HasPicked
//purpose :
//=======================================================================
Standard_Boolean Draw_Display::HasPicked() const
{
if (Draw_Batch) return Standard_False;
return found;
}