# -*- coding: iso-8859-7 -*-
##############################################################################
# ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
#
# Copyright (c) 2001-2009 Thanasis Stamos, August 23, 2009
# URL: http://thancad.sourceforge.net
# e-mail: cyberthanasis@excite.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details (www.gnu.org/licenses/gpl.html).
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
"""\
ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
Package which processes commands entered by the user.
This module processes various commands.
"""
import weakref
from math import hypot
import p_ggen, p_gtkuti
import thaneng, thandr, thancomsel, thantkdia, thanlayer, thanvers
from thanvar import Canc
from thantrans import T
from selutil import thanSel1line
from thancommod import thanModEnd,thanModCanc
def thanVarElev(proj):
"Sets the elevation in z,t and other coordinates."
nd = proj[1].thanVar["dimensionality"]
assert nd > 2, "Well, this should be ThanCad with limited n-dimensional support!"
statonce = ""
if nd > 3:
statonce = "%s\n%s\n" % (
T["This drawing has %d dimensions. The elevation and thickness"],
T["of dimensions higher than 3 are set with the ELEVN command."])
c = proj[1].thanVar["elevation"] # Reference to the elevation list
sd = proj[1].thanUnits.strdis
statonce = "%s%s %s\n" % (statonce, T["Current elevation:"], sd(c[2]))
stat = "%s%s): " % (T["New elevation (enter="], sd(c[2]))
z = proj[2].thanGudGetFloat(stat, c[2], statonce)
if z == Canc: return proj[2].thanGudCommandCan()
c[2] = z # Update elevation list
proj[2].thanGudCommandEnd()
def thanVarSudup(proj):
"Funny!."
proj[2].thanGudCommandEnd(T["Sudup, brother!"])
def thanFormLay(proj):
"Shows interactive window with layer tree in order to manipulates layers."
lt = proj[1].thanLayerTree
temp = lt.thanRoot.thanClone()
names = lt.thanCur.thanGetPathname().split("/")
cl = temp.thanFind(names)
assert cl != None, "Current layer should be found!"
w = thantkdia.ThanDialogLay(proj[2],
objs=[temp], current=cl,
atts=thanlayer.thanlayatts.thanLayAttsNames, cargo=proj,
widths=thanlayer.thanlayatts.thanLayAttsWidths,
height=15, vscroll=1, hscroll=1,
onclick=thanlayer.thanlayatts.thanOnclick,
title=proj[2].thanTitle+": Layer Control")
if w.result != None:
leaflayers, cl = w.result
lt.thanCur = cl
lt.thanRoot.thanDestroy()
lt.thanRoot = temp
lt.thanDictRebuild()
draworder = thanlayer.thanlayatts.thanUpdateElements(proj, leaflayers)
lt.thanCur.thanTkSet(proj[2].than, proj[1].thanTstyles) # Set Attributes of the current layer
proj[1].thanTouch() # Drawing IS modified
if draworder: proj[2].thanRedraw() # Set relative draworder
proj[2].thanGudCommandEnd()
proj[2].thanUpdateLayerButton()
else:
proj[2].thanGudCommandCan()
def thanFormTstyle(proj):
"Manipulates text styles."
win = thantkdia.ThanTkStyle(proj[2], proj[1].thanTstyles, "standard", lambda x: False, title=T["Edit ThanCad Text styles"])
if win.result == None: return proj[2].thanGudCommandCan()
proj[1].thanTstyles = win.result
proj[1].thanTouch()
proj[2].thanGudCommandEnd(T["Changes will be visible after the next regeneration."], "can")
def thanList(proj):
"Lists the properties of elements."
res = thancomsel.thanSelectGen(proj, standalone=False)
if res == Canc: proj[2].thanGudResetSelColor(); return proj[2].thanGudCommandCan()
than = p_ggen.Struct()
than.write = proj[2].thanCom.thanAppend
than.read = proj[2].thanGudGetText
than.writecom = lambda t, proj=proj: proj[2].thanCom.thanAppend(t, "com")
than.strang = proj[1].thanUnits.strang
than.strdis = proj[1].thanUnits.strdis
than.strcoo = proj[1].thanUnits.strcoo
dilay = proj[1].thanLayerTree.dilay
for elem in proj[2].thanSelall:
lay = dilay[elem.thanTags[1]]
than.laypath = lay.thanGetPathname()
elem.thanList(than)
del than, dilay
proj[2].thanGudResetSelColor()
proj[2].thanGudCommandEnd()
def thanEngMaprect(proj):
"Topographic map rectification using known grid points."
win = thantkdia.ThanMaprect(proj[2], None, proj)
proj[2].thanTkSetFocus()
def thanEngGrid(proj):
"Makes a set of crosses which indicate a grid."
scale = proj[2].thanGudGetPosFloat(T["Engineering scale 1:x (enter=500): "], 500.0)
if scale == Canc: return proj[2].thanGudCommandCan() # Grid cancelled
c1 = proj[2].thanGudGetPoint(T["First grid corner (Quadrilateral): "], options=("quadrilateral",))
if c1 == Canc: return proj[2].thanGudCommandCan() # Grid cancelled
if c1 == "q":
cp = getquad(proj)
if cp == Canc: return proj[2].thanGudCommandCan() # Grid cancelled
else:
c3 = proj[2].thanGudGetRect(c1, T["Other grid corner: "])
if c3 == Canc: return proj[2].thanGudCommandCan() # Grid cancelled
c2 = list(c1); c2[0] = c3[0]
c4 = list(c3); c4[0] = c1[0]
cp = [c1, c2, c3, c4]
grid = thaneng.ThanGrid()
grid.thanDo(proj, scale, 0.0, 0.0, 1, cp)
ans = proj[2].thanGudGetYesno(T["Keep grid boundary (Yes/No/<Yes>): "], default="yes")
if ans == Canc: return proj[2].thanGudCommandCan()
if ans:
e = thandr.ThanLine()
cp.append(list(cp[0]))
e.thanSet(cp)
proj[1].thanElementAdd(e)
e.thanTkDraw(proj[2].than)
proj[2].thanGudCommandEnd()
def getquad(proj):
"Get a convex quadrilateral form the user."
than = proj[2].than
g2l = than.ct.global2Local
c1 = proj[2].thanGudGetPoint(T["First quadrilateral grid corner: "])
if c1 == Canc: return Canc # Grid cancelled
while True:
c2 = proj[2].thanGudGetLine(c1, T["Second quadrilateral grid corner: "])
if c2 == Canc: return Canc # Grid cancelled
temp = than.dc.create_line(g2l(c1[0], c1[1]), g2l(c2[0], c2[1]),
fill="blue", tags=("e0",))
while True:
c3 = proj[2].thanGudGetLine2(c1, c2, T["Third quadrilateral grid corner (Undo): "],
options=("undo",))
if c3 == Canc: than.dc.delete("e0"); return Canc
if c3 == "u": than.dc.delete("e0"); break
temp = than.dc.create_line(g2l(c2[0], c2[1]), g2l(c3[0], c3[1]),
fill="blue", tags=("e0","e1"))
c4 = proj[2].thanGudGetLine2(c1, c3, T["Fourth quadrilateral grid corner (Undo): "],
options=("undo",))
if c4 == Canc: than.dc.delete("e0"); return Canc
if c4 == "u": than.dc.delete("e1"); continue
temp = than.dc.create_line(g2l(c2[0], c2[1]), g2l(c3[0], c3[1]),
fill="blue", tags=("e0","e1"))
than.dc.delete("e0")
return [c1, c2, c3, c4]
if c3 == "u": continue
def thanEngTrace(proj):
"Traces semiautomatically a curve in a bitmap image."
im, cw = proj[2].thanGudGetImPoint(T["Start point of trace: "],
ptol=proj[2].BSEL/2, threshold=127)
if cw == Canc: return proj[2].thanGudCommandCan()
proj[2].thanImageCur = weakref.proxy(im)
jx, iy = im.thanGetPixCoor(cw)
res = thaneng.thanTrace(proj, jx, iy)
if res == Canc: return proj[2].thanGudCommandCan()
return proj[2].thanGudCommandEnd()
def thanEngInterchange(proj):
"Make a highway intersection."
from thanpackages.komb.kom import thanMainTcad
lin1 = thanSel1line(proj, T["Select a line with 3 point to fit highway interchange\n"])
if lin1 == Canc: return proj[2].thanGudCommandCan()
thanMainTcad(proj, lin1)
return proj[2].thanGudCommandEnd()
def thanEngDtmmake(proj):
"Asks the user to select lines to be used as DTM."
from thanpackages import ThanDTMlines
proj[2].thanCom.thanAppend(T["Select lines to generate DTM:\n"], "info1")
res = thancomsel.thanSelectGen(proj, standalone=False, filter=lambda e: isinstance(e, thandr.ThanLine))
if res == Canc: return thanModCanc(proj) # Make dtm was cancelled
dtm = ThanDTMlines()
dtm.thanAddLines(proj[2].thanSelall)
ok, ter = dtm.thanRecreate()
if not ok: return thanModCanc(proj, T["Error creating DTM: %s"]%ter)
proj[1].thanDtm = dtm
from thansupport import thanToplayerCurrent
# thanToplayerCurrent(proj, "dtmlines", current=True, moncolor="white")
# for cp in dtm.thanLines:
# e = thandr.ThanLine()
# e.thanSet(cp)
# proj[1].thanElementAdd(e)
# e.thanTkDraw(proj[2].than)
return thanModEnd(proj, T["%d generated line segments in DTM."] % len(dtm.thanLines), "info")
def thanEngDtmpointxxxxxxxxxx(proj):
"Compute the z of a user selected point."
if proj[1].thanDtm == None: return thanModCanc(proj, T["Can't compute z: No DTM has been defined!"])
cp = proj[2].thanGudGetPoint(T["Specify a point: "])
if cp == Canc: return thanModCanc(proj) # Point cancelled
z = proj[1].thanDtm.thanPointZ(cp)
if z == None: return thanModCanc(proj, T["Can't compute z: No DTM lines are near point."])
cp = list(cp)
cp[2] = z
return thanModEnd(proj, T["Point with z: %s"] % proj[1].thanUnits.strcoo(cp), "info")
def thanEngDtmline(proj):
"Compute the z along a line."
if proj[1].thanDtm == None: return thanModCanc(proj, T["Can't compute z: No DTM has been defined!"])
proj[2].thanCom.thanAppend(T["Select lines to transform to 3d:\n"], "info1")
res = thancomsel.thanSelectGen(proj, standalone=False, filter=lambda e: isinstance(e, thandr.ThanLine))
if res == Canc: return thanModCanc(proj) # DTM lines was cancelled
dtm = proj[1].thanDtm
def prt(t, st="can1"): proj[2].thanCom.thanAppend("%s\n" % t, st)
nlin = 0
for e in proj[2].thanSelall:
ni, cp = dtm.thanLineZ(e.cp)
if ni == -1:
prt(T["Can't compute z: No DTM lines are near the selected line."])
else:
if ni > 0: prt(T["The z of some line points couldn't be computed: %d interpolations"] % ni)
e.thanSet(cp)
nlin += 1
proj[1].thanTouch()
if nlin == 0: return thanModEnd(proj, T["No lines were transformed; they are too far away the DTM."])
proj[2].thanGudSetSelDel() # Delete selected lines from canvas
proj[2].thanGudDrawElemsMany(proj[2].thanSelall) # Redraw the lines (with new coordinates)
proj[2].thanGudSetSelElem1(proj[2].thanSelall) # Mark the lines as selected
return thanModEnd(proj, T["%d/%d lines were transformed to 3d."]%(nlin, len(proj[2].thanSelall)), "info")
def thanEngDtmpoint(proj):
"Compute the z of multiple points."
if proj[1].thanDtm == None: return thanModCanc(proj, T["Can't compute z: No DTM has been defined!"])
proj[2].thanCom.thanAppend(T["Select points to transform to 3d:\n"], "info1")
res = thancomsel.thanSelectGen(proj, standalone=False, filter=lambda e: isinstance(e, thandr.ThanPoint))
if res == Canc: return thanModCanc(proj) # DTM lines was cancelled
dtm = proj[1].thanDtm
def prt(t, st="can1"): proj[2].thanCom.thanAppend("%s\n" % t, st)
nlin = 0
for e in proj[2].thanSelall:
z = dtm.thanPointZ(e.cp)
if z == None:
prt(T["Can't compute z: No DTM lines are near the selected point."])
else:
e.cp[2] = z
nlin += 1
proj[1].thanTouch()
if nlin == 0: return thanModEnd(proj, T["No points were transformed; they are too far away the DTM."])
proj[2].thanGudSetSelDel() # Delete selected lines from canvas
proj[2].thanGudDrawElemsMany(proj[2].thanSelall) # Redraw the lines (with new coordinates)
proj[2].thanGudSetSelElem1(proj[2].thanSelall) # Mark the lines as selected
return thanModEnd(proj, T["%d/%d points were transformed to 3d."]%(nlin, len(proj[2].thanSelall)), "info")
def thanEngLineprofile(proj):
"Creates a (3D) line profile into a new drawing."
from thanimp import ThanCadDrSave
from thansupport import ThanDxfEmu
from thancomview import thanZoomExt
from thancomfile import thanFileNew
proj[2].thanCom.thanAppend(T["Select 3d lines to make profiles:\n"], "info1")
res = thancomsel.thanSelectGen(proj, standalone=False, filter=lambda e: isinstance(e, thandr.ThanLine))
if res == Canc: return thanModCanc(proj) # Profile was cancelled
dfact = 0.1
for e in proj[2].thanSelall:
d = [0.0*dfact]
for ca, cb in p_ggen.iterby2(e.cp):
d.append(d[-1]+hypot(cb[1]-ca[1], cb[0]-ca[0])*dfact)
zmin = min(ca[2] for ca in e.cp)
projnew = thanFileNew(proj, mes="")
ts = ThanCadDrSave(projnew[1], projnew[2].thanCom.thanAppend)
dxf = ThanDxfEmu()
dxf.thanDxfPlots(ts)
dxf.thanDxfPlot(d[0], zmin, 3)
dxf.thanDxfPlot(d[-1], zmin, 2)
dxf.thanDxfPlot(d[0], zmin, 3)
dxf.thanDxfPlot(d[0], e.cp[0][2], 2)
for i in xrange(1, len(e.cp)):
dxf.thanDxfPlot(d[i], zmin, 3)
dxf.thanDxfPlot(d[i], e.cp[i][2], 2)
dxf.thanDxfPlot(d[i-1], e.cp[i-1][2], 2)
dxf.thanDxfPlot(0, 0, 999)
projnew[1].thanLayerTree.thanDictRebuild()
projnew[2].thanRegen()
thanZoomExt(projnew)
return thanModEnd(proj, T["%d profiles were created."]%len(proj[2].thanSelall), "info")
def thanHelpAbout(proj):
"Shows brief information about the program."
p_gtkuti.thanGudHelpWin(proj[2], thanvers.thanCadAbout, T["About "]+thanvers.thanCadName) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd()
def thanHelpHelp(proj):
p_gtkuti.thanGudHelpWin(proj[2], thanvers.thanCadHelp, thanvers.thanCadName+" "+T["Help"]) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd()
def thanHelpGpl (proj):
p_gtkuti.thanGudHelpWin(proj[2], thanvers.thanGplText, thanvers.thanCadName+" "+T["GPL"]) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd()
def thanHelpVer(proj):
"Prints ThanCad's version."
proj[2].thanCom.thanCadVer()
proj[2].thanGudCommandEnd()
def thanDevFont(proj):
"Show font for debugging reasons."
c = list(proj[1].thanVar["elevation"])
c[0] = 0; c[1] = 30; h = 50
__AddElem(proj, thandr.ThanText, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", c, h, 0.0)
c[1] -= h*1.2
__AddElem(proj, thandr.ThanText, "abcdefghijklmnopqrstuvwxyz", c, h, 0.0)
# y -= h*1.2
# __AddElem(proj, thandr.ThanText, ""+chr(255), x, y, h, 0.0)
for i in xrange(0, 256, 8):
c[1] -= h*3
c[0] = 0
for j in xrange(i, i+8):
t = "%3d:%s" % (j, chr(j))
__AddElem(proj, thandr.ThanText, t, c, h, 0.0)
c[0] += h*8
proj[2].thanGudCommandEnd()
def thanDevCm(proj):
"Gets dimension of window and screen."
w, h, width, height, widthmm, heightmm = proj[2].thanGudGetWinDim()
s = ("screen width x height (mm) : %7.1f x %7.1f" % (widthmm, heightmm),
"screen width x height (pixels) : %7d x %7d" % (width, height),
"window width x height (pixels) : %7d x %7d" % (w, h),
)
proj[2].thanGudCommandEnd("\n".join(s), "info")
def thanDevCmdsave(proj):
"Saves the content of the command window to a txt file."
import thancomfile
fout = thancomfile.thanTxtsave(proj, T["Save command window text"])
if fout == Canc: return proj[2].thanGudCommandCan()
fout.write(proj[2].thanCom.thanGet())
fout.close()
proj[2].thanGudCommandEnd(T["Save command window text was completed."], "info")
def thanDevTrans(proj):
"Save the translation report to a file."
import thancomfile
fout = thancomfile.thanTxtsave(proj, T["Save translation report"])
if fout == Canc: return proj[2].thanGudCommandCan()
T.thanReport(fout)
fout.close()
proj[2].thanGudCommandEnd("Translation report was completed", "info")
def __AddElem(proj, elemClass, *args, **kw):
"Creates an element with attributes *args on the current layer."
elem = elemClass()
elem.thanSet(*args, **kw)
proj[1].thanElementAdd(elem)
elem.thanTkDraw(proj[2].than)
|