конвертор из dxf в svg

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
>;import Data.List
>;import Data.Maybe
>;import System.Environment
>;data DxfGraphics=
> DxfLine{xStart::Double, yStart::Double, xEnd::Double, yEnd::Double}|
> DxfArc{xCenter::Double, yCenter::Double, radius::Double, aStart::Double, aEnd::Double}|
> DxfCircle{xCenter::Double, yCenter::Double, radius::Double} deriving Show
>;main=let{
> ;toPairs (x:y:s)=(x,y):(toPairs s)
> ;toPairs (x:[])=[]
> ;toPairs []=[]
> ;toDxfPair (x,y)=((read x)::Int,y)
> ;processDXF a=map toDxfPair ((toPairs.lines) a)
> ;groupDXF a = groupBy (\a (b, c) -> b /= 0) a
> ;filterDXF=let isGraphics x=let a=(snd.head) x in (a=="LINE"||a=="ARC"||a=="CIRCLE") in filter isGraphics
> ;getDxfGraphics a=let{
> ;get::[(Int,String)]->Int->Double
> ;get a i =let
> getDouble s =case reads s of [(x, "")] -> Just x; _ -> Nothing
> in fromMaybe 0 (getDouble (snd (fromMaybe (0,"0") (find (\(x,y)->(x==i)) a))))}
> in case snd (head a) of {
> ;"LINE" -> DxfLine{xStart=get a 10, yStart=get a 20, xEnd=get a 11,yEnd=get a 21}
> ;"ARC" -> DxfArc{xCenter=get a 10, yCenter=get a 20, radius=get a 40, aStart=get a 50, aEnd=get a 51}
> ;"CIRCLE"->DxfCircle{xCenter=get a 10, yCenter=get a 20, radius=get a 40}
> }
> ;toSvgPath::DxfGraphics->String
> ;toSvgPath g=case g of{
> ;DxfArc x y r a1 a2->let{
> ;lage=if (abs a2-a1)>180 then 1 else 0
> }in " M "++(show (x+r*(cos (a1*pi/180))))++" "++(show (y+r*(sin (a1*pi/180))))++" A "++(show r)++","++(show r)++" 0 "++(show lage)++",1 "++(show (x+r*(cos (a2*pi/180))))++","++(show (y+r*(sin (a2*pi/180))))
> ;DxfCircle x y r ->" M "++(show (x+r))++","++(show y)++
> " A "++(show r)++","++(show r)++" 0 0,1 "++(show x)++","++(show (y+r))++
> " A "++(show r)++","++(show r)++" 0 0,1 "++(show (x-r))++","++(show y)++
> " A "++(show r)++","++(show r)++" 0 0,1 "++(show x)++","++(show (y-r))++
> " A "++(show r)++","++(show r)++" 0 0,1 "++(show (x+r))++","++(show y)
> ;DxfLine x1 y1 x2 y2->" M "++(show x1)++","++(show y1)++" L "++(show x2)++","++(show y2)
> }
> ;toSvg::DxfGraphics->String
> ;toSvg g=case g of {
> ;DxfLine x1 y1 x2 y2 ->"<line stroke-width=\"1\" stroke=\"black\" x1=\""++(show x1)++"\" y1=\""++(show y1)++"\" x2=\""++(show x2)++"\" y2=\""++(show y2)++"\" />"
> ;DxfCircle x y r->"<circle stroke-width=\"1\" stroke=\"black\" fill=\"none\" cx=\""++(show x)++"\" cy=\""++(show y)++"\" r=\""++(show r)++"\" />"
> ;DxfArc x y r a1 a2->"<path fill=\"none\" stroke-width=\"1\" stroke=\"black\" d=\""++(toSvgPath g)++"\" />"
> }
> ;generateSvg::[DxfGraphics]->String
> ;generateSvg a="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><svg xmlns=\"http://www.w3.org/2000/svg\" >"++(foldr (++) "" (map toSvg a))++"</svg>"
> ;generateSvgPath::[DxfGraphics]->String
> ;generateSvgPath a="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><svg xmlns=\"http://www.w3.org/2000/svg\" ><path fill=\"none\" stroke-width=\"1\" stroke=\"black\" d=\""++(foldr (++) "" (map toSvgPath a))++"\"></path></svg>"
> ;breakToCycles::[DxfGraphics]->[[DxfGraphics]]
> ;breakToCycles g=let{
> ;startX (DxfLine x1 y1 x2 y2) = x1
> ;startX (DxfArc x y r a1 a2) = x+r*(cos (a1*pi/180))
> ;startX (DxfCircle x y r) = x+r
> ;startY (DxfLine x1 y1 x2 y2) = y1
> ;startY (DxfArc x y r a1 a2) = y+r*(sin (a1*pi/180))
> ;startY (DxfCircle x y r) = y
> ;endX (DxfArc x y r a1 a2) = x+r*(cos (a2*pi/180))
> ;endX (DxfLine x1 y1 x2 y2) = x2
> ;endX (DxfCircle x y r) = x+r
> ;endY (DxfLine x1 y1 x2 y2) = y2
> ;endY (DxfArc x y r a1 a2) = y+r*(sin (a2*pi/180))
> ;endY (DxfCircle x y r) = y
> ;isNext g1 g2 = (abs((startX g1)-(endX g2))<0.001) && (abs((startY g1)-(endY g2))<0.001)
> } in [[]]
>} in do {
> ;args<-getArgs
> ;if length args==0 then putStr "Nead input file\n"
> else do{
> ;a<-readFile (args!!0)
> ;(putStr.generateSvgPath.(map getDxfGraphics).filterDXF.groupDXF.processDXF) a;
> }
>}