Topic: Translating CFV source to SF

To use real dimensions of figures (i.e. in meters) I had  to make an interface between this dimensions and pixels. This is done by a module containing  graphic routines which can be used  like CVF calls which translates dimensions to screen pixels
There was a nasty problem with the scale to solve: In CVF the x and y scale of real dimensions may be different but in SF Appgraphics the scale in both directions has to be the same other wise it results in odd figures using pixels. In my CVF programs the screen resolution had influence on the x and y scale. I solved it by a control  making only one scale for both directions in the new SF versions!

An other conflict for IO-units I found between screen and printed output : in my CVF source I used predefined variable named units, three for printing and normally in CVF normally IO unit zero and 5 are reserved for the screen output. In my new SF programs  Appgraphics using several screens and dialogues, the identifier some times conflicts with my predefined IO-units

INTEGER    dlg_screen, initW
Integer    r_but(max_fr)
integer :: Ignore, contin
!    __________________________________________________________________
initW = getcurrentwindow()  ! keep the main window in memory for later use
dlg_screen = initwindow(450, 300, title = "Select a frame", closeflag = .false.)
after doing the job I finish with........

    call loop()
    Call closewindow(CURRENT_WINDOW)
    Call setcurrentwindow (initW)

I suppose that the two identifiers dlg_screen,  initW are output determined by the functions which I better should not define myself. Is that true?
Regards Klaus

Re: Translating CFV source to SF


The indentifiers generated by initwindow are not Fortran units at all.  They are simply integers used internally in the AppGraphics library for managing windows.  They are actually (but not guaranteed to be) sequential as you create windows.  You shouldn't think of them as Fortran IO units at all.  In fact, no Fortran IO calls will work with them.

That's good news that your coordinate translation routines are working well!

Jeff Armstrong
Approximatrix, LLC

Re: Translating CFV source to SF

Thanks Jeff,
I'll change my CVF based source so that the indentifiers will no more conflict with Fortran units.
If you "translate" from CVF history one will meet problems like this.

Re: Translating CFV source to SF

Hello Jeff,
I have created an odd conflict between two routines using a mouse click
There function is :
a)  move a figure given in meters by mouse a certain distance
b) zoom in the figure using ordinates in meters. This routine uses  a mouse click for both opposite corners

I can repeat both functions from the menu without crash, but if I use first one and than the other a crash follows. The message is that the program is not longer working.
A debugger error says twice SEGV Segmentation fault.
The crash occurs  inside or while starting the handle subroutine.
What happens? Could you give me a hint how to solve this problem
regards, Klaus

Here the two routines :

Routine moves world window:
SUBROUTINE PICK_MOVE_Window(x_left, y_up, x_rght, y_bot)
USE AppGraphics
integer Oldx,Oldy,MouseXpos, MouseYpos,dx, dy
DOUBLE PRECISION x_left, y_up, x_rght, y_bot, dwx, dwy, xw,yw
dwx=abs(x_left - x_rght) ; dwy= abs(y_up - y_bot)       ! window size in world window
xw = (x_left + x_rght)/2. ;  yw = (y_up + y_bot)/2.       ! current centre of world window
CALL OUTTEXTxy(10,10, 'move center by left mousebutton') !instruction text
Call DRAW_CROSS(xw, yw, dble(5.))
dx= getmaxx() ; dy=getmaxy() 
CALL MOVETO((dx/2),(dy/2))
oldx= getx()   ; oldy=gety()
!    __________________________________________________________________
Call registermousehandler(MOUSE_LB_UP, handle_click_pos)
Call loop
move_x = oldx-MouseXpos ; move_y = oldy-MouseYpos   
!New world window:
    xw = dble(move_x)/dble(dx)*dwx  ;    yw = dble(move_y)/dble(dy)*dwy
    x_left = x_left + xw ; y_up  = y_up  - yw ! new upper left corner
    X_rght = x_rght + xw ; y_bot = y_bot - yw ! new lower right corner

subroutine handle_click_pos(x, y)
    integer::x, y
    logical Clicked
Clicked = ismouseclick (MOUSE_LB_UP)
    MouseXpos = x
    MouseYpos = y
    Clicked =.false.
end if   
Call clearmouseclick(MOUSE_LB_UP)
    call stopidle   
end subroutine handle_click_pos

… in conflict with next routine used twice to zoom in a figure......
SUBROUTINE MOVE_CROSS (x_cross, y_cross, finish)
USE AppGraphics
Use W_ords_to_pixels
    Logical finish
    DOUBLE PRECISION   x_cross, y_cross
!    __________________________________________________________________
    Call registermousehandler (MOUSE_LB_DOWN, handle_click)
!    Call registermousehandler (MOUSE_RB_DOWN, handle_click)
Call loop

subroutine handle_click(x, y)
    integer::x, y   
    logical Clicked
   Clicked = ismouseclick (MOUSE_LB_DOWN)
      CAll getmouseclick (MOUSE_LB_DOWN, x, y)
      call line (x-20,y,x+20,y)
      Call line (x,y-20,x,y+20)
      x_cross = dble(real(x -x_offset))/scale_x ;  y_cross  = ywtot- dble(real(y+y_offset))/scale_y! Else
  end if   
call clearmouseclick(MOUSE_LB_DOWN)
Call stopidle ( )
end subroutine handle_click

Re: Translating CFV source to SF

The only thing I notice by looking at it initially is that handle_click in MOVE_CROSS is actually retrieving x and y coordinates again via getmouseclick, unlike the equivalent call in PICK_MOVE_Window.  This shouldn't be problem, but it does possibly change the values of x and  y in the library internally (possibly). If you don't call getmouseclick, does it behave better?

Can you tell which line it is crashing on when it claims to crash in the subroutine?

Jeff Armstrong
Approximatrix, LLC

Re: Translating CFV source to SF

hello Jeff,
The getmouseclick is removed but the crash is still the same following on pressing the left mouse button. I tested it with the debugger as well as a temporary print just after the register command and as first statement in the handle subroutines.
The debugger stops with "SEGV Segmentation fault" and i cannot find a guilty statement where it crashes after registermousehandler. The print on the console gives response after registermousehandler and not at the first line of the handle routine.

Re: Translating CFV source to SF

May be an explanation is necessary
The routines move_cross is called by the zoom procedure (see below)
Both, Zoom as well move window are called from the user menu and are starting drawing in a loop.
Repeating only one of them: no crash
but the one after the other will cause a crash

SUBROUTINE ZOOM (x_left, y_up, x_rght, y_bot)
!           Zoom in in a part of the window defined by two points using
!           the window-ordinates x_left, y_up, x_rght, y_bot with will be
!           redefined to new points, using the same aspect ratio of picture
USE AppGraphics
Use W_ords_to_pixels
INTEGER  dummy
DOUBLE PRECISION     x_left, y_up, x_rght, y_bot, lsize, ALFA
logical finish
    PRINT*,'Zoom procedure starting'
    ZoomDX = SNGL(x_rght-x_left)
    ZoomDY = SNGL(y_up  - y_bot)
      IF(ABS(ZoomDY)<.1)ZoomDY = 1.
      ALFA        =  ZoomDX/ZoomDY
      IF(ALFA < .01 .OR. ALFA > 10.)THEN
         call dlgmessage(DIALOG_INFO,'ASPECT-RATIO of graphic window out of range/ &
     Zoom function error')
      END IF
      lsize        = ZoomDX/10.   ;   Call setcolor(red)
!         Use routines _cross twice to define first point 1 than point 2 !
       CALL OUTTEXTxy   (5,5,'Click left uppercorner')
       CALL MOVE_CROSS(x_left, y_up, finish); if(finish)return
!       CALL DRAW_CROSS( x_left,y_up, LSIZE )!      Draw a cross in move mouse by pixels
       CALL OUTTEXTxy   (100,5,'Click right lowercorner')
       CALL MOVE_CROSS( x_rght, y_bot, finish); if(finish)return
!       CALL DRAW_CROSS ( x_rght, y_bot, LSIZE )!      Draw a cross in move mouse by pixels
       ZoomDX =  SNGL(x_rght - x_left)
       ZoomDY =  SNGL(y_up   - y_bot)

       IF(ZoomDY * ALFA > ZoomDX )THEN
!         redefine x-length
          x_left   =  x_left - (ZoomDY * ALFA-ZoomDX)/2.
          x_rght   =  x_rght + (ZoomDY * ALFA-ZoomDX)/2.
!         redefine y-lenght
          y_up     =  y_up   + (ZoomDX / ALFA - ZoomDY)/2.
          y_bot    =  y_bot  - (ZoomDX / ALFA - ZoomDY)/2.
       END IF
  Call setcolor(DARKGRAY)
        dummy   = rectangle_w (.true., x_left, y_up, x_rght, y_bot) ! this might be differ from the drawn crosses
        !                                                           ! because the ratio must be the same as the viewport
         call dlgmessage(DIALOG_INFO,'Zoom function finished check the zoom area within the rectangle')
        ! window redefiend directly after use of ZOOM

Regards , Klaus

Re: Translating CFV source to SF


Let me try to replicate your issue.  I'll have to write a small example program that effectively does the same thing as your code.  Clearly my examining your code snippets haven't led to a solution.  I'm sure it is an internal AppGraphics problem, though.

Jeff Armstrong
Approximatrix, LLC

Re: Translating CFV source to SF


I haven't reproduced the crash yet, but I have a few more questions. Notably, in the MOVE_CROSS subroutine, you're returning a value finished as a parameter.  Do any of your mouse handling routines actually change this value? 

Are you accessing any "global" variables at all in your mouse handling routines?  For example, are they reading or modifying a parent subroutine's variables internally at all?  The mouse handling routines are handled on a separate thread, and it can be problematic if you're reading and writing values from different handlers (or the main loop) simultaneously.

Again, I haven't seen anything technically wrong with the code you've provided thus far.  I'm just trying to determine where the issue lies.

Jeff Armstrong
Approximatrix, LLC

Re: Translating CFV source to SF

Thanks for your effort looking to my problem.
The function of parameter finish was to stop the procedure after a right button mouse click. I did remove it while testing. Parameter “finish” has now no function, it is not in use changed elsewhere in the program. I'll remover it completely.
The parameters x_left, y_up, x_rght, y_bot are global variables in the calling procedure and defined in a module but this module is not used in this mouse routines. Module  W_ords_to_pixels is used in MOVE_CROSS (see below). The scale variables are used in “handle_click” but not changed.
The scale parameters are defined in function setwindow which is also contained in W_ords_to_pixels  but will never be changed elsewhere.
Should it help to use different names internal the mouse handler for the scale as well as for the corner points in m?
Thanks so far.
Regards, Klaus

Module W_ords_to_pixels
Use AppGraphics
Real*8 xw,xwtot, scale_x
Real*8 yw,ywtot, scale_y
Integer dx,dy, x_offset, y_offset
TYPE wxycoord
      Real*8 x
      Real*8 y
end type wxycoord
TYPE (wxycoord)wxy

!!!!! ===================== warning ==============================!!!!! a
! The pixel window to show graphics has to be opened prior to apply this function !!!!!

Function setwindow (origin , x_left, y_up, x_rght, y_bot)    ! same as CVF but little changed functionallity!!
! i2   = setwindow (.TRUE.   , x_left, y_up, x_rght, y_bot)  ! make this work in module
        ! make returnvalue =1 if OK, otherwise 0
! In this this function a world coordinate system y from top down is not defined and has to return zero (diff from CVF)
integer setwindow
logical origin     ! to be true for lower left corner and y up warts
Real*8 x_left, y_up, x_rght, y_bot !virtual world corners of the viewport
                    ! If negative lower left corner there is an offset to the origin xw,yw = 0.,0.
Real*8 dxw, dyw    ! absolute "world"dimensions in xy direction
integer dx, dy
setwindow = 0

! the window size in world ordinates is defined by the arguments of this routine!!!!!!!!!!!!!!!!!!
dxw = x_rght - x_left
dyw = y_up - y_bot
If(dxw == 0.)setwindow = -1
If(dyw == 0.)setwindow = -2
If(.not. origin)setwindow = -3
If(setwindow <0) return

! get the pre-defiened window size of the CURRENT window in pixels x,y may be the max screen or lower defined
dx = getmaxx()
dy = getmaxy()

! ****************************************
! WARNING: the scale of the screen between real world orinates and screen resolution has to be the same for x and y
! because the appgraphics functions only knows one scale for instance circles and elipses.
! It is NOT possible to stretch a figure more in one direction unless unrealible figures will be shown!!!
!  If scale_x is not scale_y, scale_x should be recalculated with or without warnimg dlg
!   *************************************

IF(dx > 0 .and. dy > 0 )then
    ! only works in a predefined actual window!
     xwtot = dxw           !  May ..tot should be replaced by  ..w !!!
     scale_x = dble(dx)/dxw
     x_offset= -int(x_left*scale_x)
     ywtot = dyw
     scale_y = dble(dy)/dyw
     y_offset= -int(y_bot*scale_y)       ! test pos or neg
!  End subroutine init_world_window
setwindow =1 ! does not work with origin in top left

End if
If(scale_x/scale_y < dble(0.95) .or. scale_x/scale_y>dble(1.05))then
print*,'scale x and y',scale_x,scale_y
dxw=dble(dx)/scale_y; scale_x=scale_y
x_left =dxw - x_rght
call dlgmessage(dialog_warn,'scale in x and y direction whers not the same. Scale x is corrected')
end if
End function setwindow

Re: Translating CFV source to SF


I'm still investigating your problem, but I still haven't replicated the crash.  On what version of Windows are you experiencing the crash?

I think I'm going to have to use your snippets exactly as you've provided and create a wrapper around them.  I can't seem to build a simplified case where the crash occurs based on your descriptions and code.

Jeff Armstrong
Approximatrix, LLC

Re: Translating CFV source to SF

Hello Jeff,

Sorry about the struggle with the nasty crashes....
Your question about my windows version: I have upgraded windows from 7 to 10 a half year ago.

To explain how my program works the following. There are several user levels. This is the so called "cross section level". Starting this levels also a view menu is defined with 5 sub menus :

menu_control = Addmenuitem (menutxt2(1),2, CrossMen2_1) ! Zoom
menu_control = Addmenuitem (menutxt2(2),2, CrossMen2_2) ! Reset view
menu_control = Addmenuitem (menutxt2(3),2, CrossMen2_3) ! Show-options
menu_control = Addmenuitem (menutxt2(4),2, CrossMen2_4) ! Rotate 3-D
menu_control = Addmenuitem (menutxt2(5),2, CrossMen2_5) ! Move Window
menu_control = Addmenuitem (menutxt2(6),2, CrossMen2_6) ! Select single frame

All these external menu routines only defines a menu id and item as follows: 
! _________________    Menu id 2 -- view_______________________________
subroutine    CrossMen2_1
menuid=2; menuitem =1
Call Navi_CrossSec
end subroutine

subroutine    CrossMen2_5
USE CASTORglobals;
        menuid=2; menuitem =5
Call Navi_CrossSec
end subroutine
All menu routines are calling “Navi_CrossSec” where selection is made  (after a initialization, only the first time of call) as follows:
CrossMenu: Select CASE (menuid)
!    ______________________    menuid 1: files - menu______________________________
        CASE (1)               
        Select CASE (menuitem)
            CASE (5); CALL Save_section    ! Save all parts and current active ordinates
            CASE (8); CALL Export_sec(N_SPT)!  Export to DXF-file start here here (Make options )
        END SELECT

!    ______________________    menuid 2: View - menu_______________________________
        CASE (2)   
        SELECT CASE (menuitem)
                        CASE (1)    ;    CALL ZOOM(x_left,y_up,x_rght,y_bot)
             CASE (2)    ;    N_SPT = 0    ! Reset to original view
              INCLUDE 'WIN_Reset.fd'        ! Real window-size related to the ship's dimension same as above-----
                 dummy    = setwindow(.TRUE., x_left,y_up,x_rght,y_bot)                    CASE (3);    CALL Show_Options_dlg(V_OPT) ! define view options
            CASE (4);    CALL rotate_3_D(rx,ry,rz,V_OPT)! Rotate the 3-d view
            CASE (5);   Call PICK_MOVE_Window(x_left,y_up,x_rght,y_bot)! Move window by mouse pick              
at the end always follows the drawing procedure:

End Select CrossMenu
   13     Menuitem = 0 !Reset item after finishing each selected procedure
!    _____________________START visual resentations________________________________________
!    Set graphic window related to the extension of the cross section
    dummy= setwindow   (.TRUE., x_left, y_up, x_rght, y_bot)
    if(dummy == 0) call dlgmessage(DIALOG_Warn,'Bad window settings for visual presentations')   
    call clearviewport
!              Graphic presentation of structural parts on cross section
    IF(V_OPT(8) .and. N_SPT <=0)Then
        Call  View3_D(Framesetlist,V_OPT,ry,rz) ! calling view_section in a loop for all defiend active frames
        CALL  view_section(N_SPT,.False.)        ! part of file SectionDrawing.f90 - param dxf here false
    end if
!    ____________________end  of visual presentations
Please take into account that the way how the whole program is build, has a history from the middle of the 90ties until now.
About the crashes: They are not inside the view routines but in the routines of menu id 2 item 1 or  5!
Its crazy that I can repeat zoom or move window separate from each other endless but the next call of  the other one causes the crash just starting the mouse handler. Why?????

Further more the variables x_left, y_up, x_rght, y_bot are global and defined in module “StrPartGlobals” for “Navi_CrossSec” but not in zoom and move window.
Zoom and move window are contained in a separate library and they use the module “W_ords_to_pixels” also where scale_x and _y are defined.
I hope to give an overview how the program is built.

Meanwhile I am working on a next program level with the same structure using also the view options. Looking forward I will see if the problems are the same.
For the user version I can switch off move window preliminary until the problem is solves.
Tanks very much for all your effort you spent in this problem.
Regards Klaus